BlankTar

about | blog | works | photo

昨日のディレクトリ操作に引き続いて、本日はElixirでファイル入出力をやってみます。

簡単な読み書き

単純に読み込む/書き込むだけならものすごく簡単で、以下のように出来ます。

iex> File.write "test.txt", "hello"
:ok
iex> File.read "test.txt"
{:ok, "hello"}

iex> File.write "test.txt", " world", [:append]
:ok
iex> File.read "test.txt"
{:ok, "hello world"}

一回目の書き込みが通常の上書き的な書き込み、二回目の書き込みが追記書き込みになっています。
File.writeの第三引数にオプションを渡すわけですね。使えるオプションについては後述。

ファイルハンドラを使った読み書き

一般的なopenしてwriteして…って流れでも読み書きが出来ます。以下のような感じ。

iex> File.write "test.txt", "はろーわーるど"
:ok

iex> {:ok, fp} = File.open "test.txt"
{:ok, #PID<0.100.0>}

iex> IO.binread fp, 3
"は"

iex> File.close fp
:ok

デフォルトでは読み込みモード、バイナリモード?で開かれるようです。
IO.binreadの第二引数はバイト数です。3文字読みたかったのに1文字しか返って来ませんでした。

ファイルがutf-8で保存されているなら、utf-8モードが使えます。

iex> {:ok, fp} = File.open "test.txt", [:utf8]
{:ok, #PID<0.100.0>}

iex> IO.read fp, 3
"はろー"
iex> IO.read fp, 4
"わーるど"
iex> IO.read fp, 1
:eof

iex> File.close fp
:ok

IO.binreadではなくてIO.readになりました。ちゃんと文字数で指定出来ています。
ファイルの終了まで行ったら:eofが返るのもポイントですね。

書き込みも何の捻りもなく以下のように行ないます。

iex> {:ok, fp} = File.open "test.txt", [:write, utf8]
{:ok, #PID<0.100.0>}

iex> IO.binwrite fp, "はろー"
:ok

iex> File.close fp
:ok

iex> File.read "test.txt"
{:ok, "はろー"}

openするときにオプションに:writeを渡すだけです。

オプション

:read:writeはそのまんま読み込みモード/書き込みモードです。
両方指定すると読み書き両方出来るようになります。
:readを指定しているときは存在しないとエラーに、:writeを指定しているときは存在しなければ作るようです。

:appendを指定すると追記書き込みになります。上でちょこっと使ったやつです。
存在しない場合は新規作成になります。

:exclusiveオプションを:writeと同時に使うと、ファイルが存在するとエラーが返るようになります。
新規作成だけを認める場合に使うオプションですね。

:char_list:utf8を使うと読み込んだときに返る型を決められるようです。
何も付けないとbinaryで返るようになっています。
エンコーディングについては:utf16utf32:big:littleなど、色々オプションがあるようです。

:compressedを付けるとファイルがgzipで圧縮されるようになります。
圧縮レベルなどのオプションもあるのかもしれませんが、見付けられませんでした。

:delayed_write:syncを付けると、書き込みを即座に行なうかバッファするかを選べます。
デフォルトでは:syncのようです。細かく沢山書き込むときは:delayed_writeにしておくのが賢いのかも?

参考:
File - Elixir v1.2.5
IO - Elixir v1.2.5

< Elixirでファイルの一覧とかのディレクトリ操作 ElixirのAgentモジュールを使って値の更新とかメモ化とか >