2019/05/07

Rustでファイルに追記したい場合

fs::OpenOptions

CSVデータをファイルに保存しようと思った時のことでした。
「あれ?そういえばfs::File::openでモードはどうやって設定するのだろう?」

Pythonでは以下のようにモードを設定できます。

with open(ファイル名, モード) as f:
モードの箇所にr/w/x/aとt/bの組み合わせで設定します。
Pythonの場合だと
  • rは読み出し
  • wは書き込みでファイルがまだ存在しない場合は新たにファイルが作られ、存在する場合は上書きされる
  • xはファイルがまだ存在しない場合のみ書き込み
  • aはファイルが存在する場合、末尾の後ろに追記
  • tはテキスト
  • bはバイナリ
C言語の場合のfopenもr/w/aを使用し、以下のようになります。

FILE *fp;
fp = fopen(ファイル名, モード);
このaモードつまり追記モードはどうすればよいのか調べていましたところ、このfs::OpenOptionsを見つけました。使い方は以下のようになります。

use std::fs::OpenOptions;

let file = OpenOptions::new()
    .append(true)
    .open(ファイル名)?;
ファイルが存在する場合は、これで追記モードで開くことができます。また内容を一新したい場合は、以下のような方法でまっさらな状態でファイルを開くことができます。

use std::fs::OpenOptions;

let file = OpenOptions::new()
    .write(true)
    .truncate(true)
    .open(ファイル名)?;
これらはあくまでファイルをどのモードで開くかということなので、このあとWriterBufWriterなどで書き込む処理を行います。この部分はまた別のお話。
Pythonではwith文を使うと、処理終了後、自動でファイルを閉じてくれます。C言語の場合は、close()しなければいけませんが、Rustの場合は、ドロップされると自動でファイルは閉じてくれますので、close()する必要はありません。
さらにRustの便利な?マーク。これは値がResultの場合に使える代物で、上記の場合だと、「ファイル上手く開けた?」と聞いているようなものです。したがって、これらの処理をしている関数の返り値はResultであり、OkErrのいずれかであります。
私のように知らなかった方はぜひこの機会に一度公式ドキュメントを調べてみてください。

オススメ書籍