Java Programming Language

Javaではさまざまな方法でファイルのコピーを実装できる。Javaプログラマなら誰しも一度は、どの方法がもっとも高速にファイルコピーを実現できるか考えたことがあるだろう。プログラマにとって実行速度はいつでも最大の関心事のひとつだ。

File Copy in Java - Benchmark - Javalobbyに、こうした疑問に対するひとつの結果として興味深い記事が掲載されている。Baptiste Wicht氏が投稿した記事で、コピー実装を10の種類に分類し、それぞれどういった違いが現れるかを紹介している。コピー方法は次のとおり。

  1. 読み込みと書き出しのStreamを開いて、byteごとにファイルのコピーを実施。
  2. 読み込みと書き出しのReaderを開いて、charごとにファイルのコピーを実施。
  3. 読み込みと書き出しのBufferdStreamを開いて、byteごとにファイルのコピーを実施。
  4. 読み込みと書き出しのBufferedReaderを開いて、charごとにファイルのコピーを実施。
  5. 読み込みと書き出しのStreamを開いて、4KBのbyte配列をバッファとして使って使ってファイルのコピーを実施。
  6. 読み込みと書き出しのReaderを開いて、4KBのbyte配列をバッファとして使ってファイルのコピーを実施。
  7. 読み込みと書き出しのBufferedStreamを開いて、4KBのbyte配列をバッファとして使ってファイルのコピーを実施。
  8. 読み込みと書き出しのBufferedReaderを開いて、4KBのbyte配列をバッファとして使ってファイルのコピーを実施。
  9. NIOチャンネルとByteBufferを使ってファイルのコピーを実施。
  10. NIOチャンネルを使ってチャンネル間でダイレクトにファイルのコピーを実施。

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmark - Javalobbyより抜粋

File Copy in Java - Benchmarkでは最終的に次の指針を紹介している。

  • 5MB以上のファイルにはNIOチャンネルを使った転送コピーが効果的
  • 5MB以下のファイルにはバッファをカスタマイズしたStreamコピーが効果的

また、ファイルをコピーする実装を記述する場合の注意点として次の説明もある。

  • バイトごとにコピーしない。
  • バッファを活用する。
  • バッファサイズに注目する。
  • コピーのみを目的とする場合、文字変換は実施しない。
  • チャンネルを活用する。

File Copy in Java - Benchmarkで紹介されているベンチマーク結果は利用するOSやJDKのバージョンによって変わる可能性がある。特にOSやファイルシステムの違いはそのままベンチマーク結果に影響を及ぼすため、File Copy in Java - Benchmarkの内容は参考程度に留める必要がある。しかし、バイトごとにStreamでコピーするのは効率が悪いことや、コピーするだけなら文字変換を実施しないストリームの方が効率がいいなど、的を射った指摘もあり、参考になる。