【Java】ファイル出力方法の調査メモ

f:id:hira98:20190604073716p:plain

【結論】

  • PrintWriterクラスを使えば、ターミナルへ文字列を出力していたのと同じ感覚でファイルへ出力できる。
  • PrintWriterクラスだけで実現できるのに、BufferedWriterクラスも使う理由を検証してみた。
  • しかし、BufferedWriterクラスを使う理由は分からなかった。

【目次】

ファイルへ出力する方法

以下の記事を参考にしました。

tech.pjin.jp

サンプルソースへの疑問点

サンプルではFileWriterBufferedWriterPrintWriterと3つのクラスを利用しています。そこで、各クラスの用途を調べてみると。

FileWriter f = new FileWriter("sample.csv", false);
PrintWriter p = new PrintWriter(new BufferedWriter(f));
p.println("Hello World");

という処理は、PrintWriterクラスだけで実装できる事が分かりました。

PrintWriter p = new PrintWriter("sample.csv");
p.println("Hello World");

なぜ?PrintWriterだけで実装できる処理をFileWriterBufferWriterまで使う必要があるのか気になりました。

予想として、時間かかるファイルへの書き込み処理をまとめて行う事で処理速度を上げるためにBufferWriterを使っているのでは?と思いました。この予想が正しいかを検証するために、書き込み速度を比較してみました。

検証用ソース

実装したソースは以下になります。

java Test [書き込みモード(1/2)] [書き込み行数]で呼べるようにしました。

書き込みモードはBufferWriteの使用有無(1:使う / 2:使わない)です。

検証方法

各書き込みモードで、1億行の書き込みにかかった時間を5回測定して集計します。

# 実行コマンド
$ time java Test 1 100000000
$ time java Test 2 100000000

検証結果

検証結果を下表にまとめました。

書き込みモード1(BufferedWriter使用)

回数 real user sys
平均 13.280 11.731 1.216
中央 13.263 11.915 1.211
最大 13.524 11.952 1.309
最小 12.931 11.325 1.170

書き込みモード2(BufferedWriter未使用)

回数 real user sys
平均 13.550 11.937 1.226
中央 13.716 12.072 1.239
最大 13.921 12.170 1.278
最小 12.806 11.564 1.145

結果の考察

1億行(文字だけで1GB)書いているはずなんですが、殆ど差がありませんでした。

僅かに書き込みモード1が速いですが誤差レベルです。

ただし、「BufferWrite使っても速度かわらないならPrintWriteだけ使えばいい。」と結論を出してしまうのは早過ぎると思っています。

  • 検証に使ったPCはSSD搭載なので差がほとんどなかっただけで、HD搭載PCで測定するとどうなるか?

  • 検証に用いたソースは正しいのか?

  • …etc

というような点も検証していく必要があると思います。わざわざBufferWriterクラスを用意するからには何かしらの利点があるはずですから。

参考情報

【Java】CSV出力のサンプルコード | TECH Projin

BufferedWriter (Java Platform SE 8)

PrintWriter (Java Platform SE 8)

最後に

試したソースも載せていくスタイルです。