- ベストアンサー
ファイル読み込み/書き込み速度を上げるには
下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか? BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data")); BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data")); int c ; while((c = in.read()) != -1) { out.write(c); } in.close(); out.flush(); out.close();
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
速くなるかどうかは環境によって微妙に違うと思いますが、効率よくやる方法が2つあります。 1. 1バイトづつ読み書きするのではなくて byte[] で1000バイトとかの塊を読んでそのまま塊を書くようにする。(こうすると read, write をする回数が減るので少し速いと思います)。 2. FileInputStream と FileOutputStream のインスタンス双方から getChannel() で java.nio.channels.FileChannel のインスタンスを取り出し、FileOutputStream 側から取り出した FileChannel のインスタンスに対して transferFrom() で FileInputStream 側から取り出した FileChannel のインスタンスを指定する。 例) in は FileInputStream のインスタンス, out が FileOutputStream のインスタンスの場合。 FileChannel fcin = in.getChannel(), fcout = out.getChannel(); fcout.transferFrom(fcin, 0, fcin.size());
その他の回答 (4)
- unibon
- ベストアンサー率47% (160/340)
> byte[] aa = new byte[10]; > while((c = in.read(aa)) != -1) > { > out.write(aa); > } このままだと、たとえば4バイトしか読んでいないのに10バイトを書いてしまい、お尻に6バイトのゴミが付いてしまいます。 変数 c に読めたバイト数が入りますので、これを書き込み時に使う必要があります。 out.write(aa, 0, c); とすれば良いです。 なお、バッファ処理を自前の配列を使ってやるのならば、 BufferedOutputStream/BufferedInputStream を使う必要はありません。FileOutputStream/FileInputStream をじかに使えば良いです。 しかし、自前の配列によるバッファと、BufferedOutputStream/BufferedInputStream のバッファを組み合わせて使っても、別段悪影響が出るわけではありません。
- nfonfonfo
- ベストアンサー率63% (12/19)
Javaにこだわらないならこういう方法もあります。 java.lang.Runtime,exec("copy sample1.data sample2.data"); まずボトルネックがどこかprofilerで計測してみては?
- Bonjin
- ベストアンサー率43% (418/971)
>out.write(aa); ではなくて out.write(aa, 0, c); です。 何故かはJavaDocを見て勉強して下さい。
- unibon
- ベストアンサー率47% (160/340)
Java の API の Buffered~ 系のクラスは、バッファーサイズのデフォルト値がとても小さいです。 BufferedInputStream や BufferedOutputStream は 8192 バイトのようです。 以前のバージョンだとさらに小さかったかもしれません。 BufferedInputStream も BufferedOutputStream も、コンストラクターの引数でバッファーサイズを指定できますので、メガバイト単位の大きな値を指定したほうが良いです。
補足
noboru2000さんのアドバイスも加味して下記ソースコードにて実行したのですが、実行後のファイルサイズが下記のようになりました。 sample1.data 37,105,664 バイト(コピーもと) ↓ sample2.data 37,105,670 バイト(コピー) ファイルサイズが変わった原因はなんなのでしょうか。 コピーもとのファイルはバイナリの画像ファイルです。 コピー後のファイルに破損はありませんでした(正常に画像が表示されました)。 <ソースコード> import java.io.*; class IO_Test { public static void main(String args[]) { try { BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data"),1000000); BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data"),1000000); int c ; byte[] aa = new byte[10]; while((c = in.read(aa)) != -1) { out.write(aa); } in.close(); out.flush(); out.close(); } catch(Exception e) { e.printStackTrace(); } } }