April 17, 2005

自由自在 Squeak プログラミング:第6章 基本クラスライブラリ探検─その2(3)

Squeak Logo
<ストリームクラス群>:ストリームは一続きのデータを処理するもので、必ずなんらかのコレクション(クラスのインスタンス)を元に生成するが、殆どの場合は String を扱う時に利用される。

外部ストリーム:ファイルやソケットを介して、Squeakの外とやりとりするためのストリーム
FileStream:ファイルに対して読み書きを行うストリーム。
基本的な使い方は、ファイルストリームオブジェクトをファイル名を指定して生成し、データを書き込み/読み込み後、ファイルストリームを閉じる。
ファイルストリームを閉じ忘れると、Squeakを終了するまでファイルにアクセスできない。
 ファイルへ書き込む例:
  fs := FileStream newFileNamed: 'test.txt'.
  fs nextPutAll: 'テスト', (Character cr) asString, 'です'.
  fs nextPut: Character cr.
  fs close. "do it"
 ※:同じファイル名で書き込もうとすると、上書きか、名前を変えるか、キャンセルするかのダイアログが表示される。
 ※:日本語版Squeakの場合、文字コードはUTF-8、改行コードはCR(Character value: 13)になる。
 ファイルを読み込む例:
  fs := FileStream readOnlyFileNamed: 'test.txt'.
  Transcript cr.
  [fs atEnd] whileFalse: [Transcript show: fs next; space. ].
  fs close. "do it"
 ※:ファイル読み込み時も、最後にファイルストリームを閉じる事を忘れないようにする。
 バイナリファイルを書き込む例:
  fs := FileStream newFileNamed: 'test.bin'.
  fs binary. "ファイルストリームをバイナリモードに設定する"
  fs nextPutAll: #(84 69 83 84 13) asByteArray. "配列をByteArrayにキャストして書き込み"
  32 to: 122 do: [:temp | fs nextPut: temp. ]. "32から122までを書き込む"
  fs close. "do it"
 ※:バイナリファイルへの書き込みは、0から255の整数のみに制限されている。
改行コードの扱い:Mac(Squeak)=CR(Character value: 13), Unix=LF(Character value: 10), Windows=CR, LF(Character value: 13, Character value: 10)
Squeakはマルチプラットフォームで動作するので、改行コードを区切りにしたい場合、FileStreamのサブクラス「CrLfFileStream」クラスを利用する。
 1行毎に読み込む例:
  fs := CrLfFileStream fileNamed: (FileStream fullName: 'test.txt').
  [fs atEnd] whileFalse: [Transcript cr; show: (fs upTo: Character cr).].
  fs close.
 ※:自由自在のサンプルそのままのFileStream fullName: はマルチバイト対応? 無くても動く事は動くが…。
その他の重要なストリーム
(1) RWBinaryOrTextStream:FileStreamの内部メモリ版(WriteStreamのサブクラス)で、大きなデータをいきなりファイルに書かない場合に利用。また、ReadStrem, WriteStreamの様に任意のオブジェクトではなく、バイト列と文字列に最適化されている。
 Stringを指定して生成する例:String new: を ByteArray new: にすると、バイトモードになる。
  ws := RWBinaryOrTextStream on: (String new: 50). "StringでRWBinaryOrTextStreamを生成"
  ws nextPutAll: 'Character value:33, 34, 35, 36, 37 = '. "文字列をセット"
  ws nextPutAll: (#(33 34 35 36 37) asByteArray). "バイト列をセット"
  ws contents. "print it"
 生成時に指定せず、インスタンスに明示的にメッセージを送る例:
  rws := RWBinaryOrTextStream on: (String new: 10).
  rws nextPutAll: 'Squeak!'.
  rws contents. "ここで print it すると、String new:で生成したので文字列"
  rws binary.
  rws contents. "ここで print it すると、binaryメッセージを送ったのでバイト列"
  rws text.
  rws contents. "ここで print it すると、textメッセージを送ったのでまた文字列"
(2) TranscriptStream:WriteStreamのサブクラスで、そのインスタンスは、グローバル変数 Transcript にバインド(代入)されている。(Transcript inspect. すると、インスペクタのタイトルがTranscriptStreamになっている。)
 Transcript cr; show: 'Squeak!'. を分解した例:Transcript browseHierarchy でインスタンスメソッドshow:を参照
  Transcript nextPut: Character cr. "改行を追加"
  Transcript nextPutAll: 'Squeak!'. "文字列を追加"
  Transcript endEntry. "表示を更新"
(3) DataStream, ReferenceStream, SmartRefStream:複雑な構造を持つオブジェクトを、コンパクトなバイト列へ変換し、保存/復元するストリーム群。
 i. DataStream:比較的単純なデータを保存/復元するのに利用。
 ii.ReferenceStream:複雑な参照関係を持ったオブジェクトを保存/復元するのに利用。
 iii.SmartRefStream:ReferenceStreamの拡張版で、インスタンスのクラス情報もバイト列に含まれる。
 DataStreamの例:外部ストリーム
  ds := DataStream fileNamed: 'objects.bin'. "ファイル名を指定して生成"
  ds nextPut: '今日は : '. "String オブジェクトの書き込み"
  ds nextPut: Date today. "Date オブジェクトの書き込み"
  ds close.
  書き出したファイルからバイト列を読み、オブジェクトに戻す例
  ds := DataStream fileNamed: 'objects.bin'. "ファイル名を指定して生成"
  [ds atEnd] whileFalse: [ Transcript cr; show: ds next. ]. "バイト列からオブジェクトに復元"
  ds close.
 DataStreamの例:内部ストリーム(クラスメソッドを使用)
  sb := DataStream streamedRepresentationOf: '日本語'. "バイト列化して保存"
  Transcript cr show: (DataStream unStream: sb). "バイト列からオブジェクトに復元"

ensure: による閉じ(close)忘れの防止:エラー処理構文
書き方:[エラーが起きるかもしれない処理] ensure: [エラーの有無に関わらず実行する処理]
 例:エラー画面の[Abandon]ボタンをクリックしても、ensure: ブロックは必ず実行される。
  [ans := Time now seconds ¥¥ 2.
  Transcript show: '1 / ', ans asString, ' = '.
  ans = 0 ifTrue: [Transcript show:'エラー!! ZeroDivide:[Abandon]をクリック'. 1 / ans.]
  ifFalse:[Transcript show: 1 / ans].
  Transcript show:':計算されました。'.
  ] ensure: [Transcript show:':ensure:を実行'; cr.].


Posted by 3k1 at 02:33 P | from category: Squeak | TrackBacks
Comments
No comments yet
:

:

Trackbacks