みなさん、こんにちは。
この講義では ファイル操作のAPIを見ていきます。
特に
ファイル間のナビゲーション
ファイルの生成と削除
ディレクトリ内のファイルのリスト
ファイルへの読み書きを見ていきます。
最初に
ファイルシステムへの入り口が必要です。
入り口はたくさんあります。
FileLocator home でユーザーディレクトリが得られます。
FileLocator root でファイルシステムの
ルートが得られます。
FileLocator C で Windows での C ドライブが得られます。
これらの 3 つはどれもディレクトリです。
ディレクトリが得られれば
例えば FileLocator home で
ユーザーのホームディレクトリが 得られれば
そこから
「アクセスパスをください」 と言うことができます。
つまり home は文字列ではなく ディレクトリを表現した
オブジェクトで 「ファイルシステム中であなたを
指定する文字列をください」と お願いすることができます。
この場合、 /home/cassou です。
ディレクトリに その子要素を訊くことができます。
「あなたが持っている全ての ファイルとディレクトリは？」と。
ここに home からの答えがあります。
.bashrc という名前のファイルや
Music ディレクトリです。
この children は
ファイルとディレクトリを表す
オブジェクトの束を返します。
この API をもう少し掘り下げると
/ メソッドがあります。
/ メッセージをディレクトリへ送ると
その特定の子要素を示すことができます。
home / 'Music' で Music ディレクトリが得られます。
directories メッセージを ディレクトリに送ると
全てのサブディレクトリが得られます。
ここに見える通り 私の Music ライブラリには
Anouar_Brahem があります。
parent メッセージで上の階層に 上がっていくことができます。
Music ディレクトリに parent を送ると
home ディレクトリが得られます。
Music ディレクトリから離れて
ディレクトリを作りたいと思います。
まずディレクトリが存在するかどうか 確認するために
isDirectory メッセージを送ります。
するとディレクトリが存在するかどうか が得られます。
存在しないようです。
では ensureCreateDirectory で 作ります。
そして存在するかどうか確認すると 今回は存在します。
delete で削除できます。 そして削除できたか確認するために
isDirectory を送ります。
ディレクトリ中の子要素を
探すためには
いくつかの方法があります。 そのうち 2 つをお見せします。
allChildrenMatching: メッセージを ディレクトリに送って
表現式を渡します。
表現式は
期待する子要素の名前を示します。 この場合、*.ogg です。
拡張子 .ogg を持つ全てのファイルを 求めています。
すると PinkFloyd ディレクトリの .ogg の音楽ファイルが得られます。
同じことを長いコードでもできます。
allChildren メッセージを送って
特定のディレクトリの 全てのファイルやディレクトリを得て
select: メッセージでフィルタします。
basename でファイル名の文字列が 得られ
名前が ogg で終わるものを
選びます。
この 2 つのコードはほとんど同じです。
ファイルについての情報を どうやって得るのか
文字列からファイルをどうやって作るのか
ファイル名があるので asFileReference で
ファイル名からファイルへの参照を得ます。
そのファイルは存在しているかもしれないし まだ存在していないかもしれません。
参照に isFile メッセージを送ると
参照先のファイルが存在すれば true 存在しなければ false になります。
basename メッセージを送ると そのファイルの名前が得られます。
extension を送ると ファイルの拡張子が得られます。
size でファイルサイズが得られます。
pathString は先程も使いましたが
ファイルへのパスを文字列形式で得られます。
さて、ではファイルへの読み書きを 見てみましょう。書き込みですが
まず最初にファイルへの参照を作ります。
ここで、参照先が存在しないことを確認します。
ファイルは存在していません。
書き込むためには ストリームを作成します。
nextPutAll: で
文字列中の各文字をファイルに書き込みます。
最後にストリームを閉じて、確実に
システムに全てを書き込みを完了させます。
反対に、ファイルから読み込むためには
.txt ファイルについて
存在するか確認します。もちろん存在します。 さきほど書き込んだので。
readStream で 読み込み用のストリームを作成します。
next を送って文字を見ていきます。
next メッセージで h、e、l、…を得ていきます。
最初の next で h が得られ
続いて、残り全てを取り出します。
h を読んでからファイルの最後までを 読み込みました。
これで 最初の「h」を除いた 「ello World」が得られます。
最後にストリームオブジェクトに close を送って to the stream object,
ファイルを確実に閉じます。
close メッセージを使わずに
もっと簡単なコードで
書くことができます。
close メッセージを送り忘れたり することがあります。
ファイルが閉じられていないために 例外が発生することもあります。
一般的に、自分で close を書かずに 済ませたいところです。
そのためには、書き込みでは
ファイルへの参照へ
writeStreamDo: メッセージを送ります。
引数としてブロックを渡すと
そのブロックが引数として ストリームを受け取ります。
このストリームは writeStreamDo: が
そのファイルへの書き込み用ストリームとして 自動的に作って管理してくれます。
私がこのストリームでしなければならないことは
そのファイルでやりたいことをするために ストリームを操作するだけです。
「Hello World」をファイルに書き込むには stream nextPutAll: 'Hello World' とします。
ブロックが終了すると
ストリームが自動的に閉じられて ファイルがディスクに書き込まれます。
読み込みでも readStreamDo: で 同じことができます。
ここでストリームが得られて 好きなように操作します。
ここでストリームの内容を受け取ります。
今回学んだことをまとめます。
ファイルやディレクトリは参照です。
ディスク上のファイルやディレクトリ への参照です。
参照先は存在しているかもしれないし 存在していないかもしれません。
isFile や isDirectory で 存在するかどうかを確認します。
API はシンプルです。
ファイルのナビゲーションや操作を 提供します。
ファイルの読み書きを ストリームを使って行います。
最後にストリームを閉じることを
自動的にやってくれる API があります。