
下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか?
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();
No.1ベストアンサー
- 回答日時:
速くなるかどうかは環境によって微妙に違うと思いますが、効率よくやる方法が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());
No.5
- 回答日時:
> 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 のバッファを組み合わせて使っても、別段悪影響が出るわけではありません。
No.4
- 回答日時:
Javaにこだわらないならこういう方法もあります。
java.lang.Runtime,exec("copy sample1.data sample2.data");
まずボトルネックがどこかprofilerで計測してみては?
No.2
- 回答日時:
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();
}
}
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
VB.NET getとsetの概念がわかり...
-
C#において、同じインスタンス...
-
クラスのインスタンス名をクラ...
-
C# インスタンスの破棄
-
複数の変数を宣言する時、同時...
-
private static という変数の修飾
-
エクセル(複数インスタンス)...
-
変数の参照でエラーが出てしま...
-
objective-cで分かりにくい所教...
-
インスタンスのハンドル
-
C#の構造体の開放のしかた
-
[VB.NET] インスタンス生成とイ...
-
JSPでの表示
-
オブジェクト参照がオブジェク...
-
SQLを連続発行する時の正しい(?...
-
Eclipse3でVisualEditorが起動...
-
VB.NET Newしたものを変数に代...
-
抽象クラスのインスタンス生成...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
インスタンス参照でアクセスで...
-
変数名の付け方
-
private static という変数の修飾
-
C#において、同じインスタンス...
-
複数の変数を宣言する時、同時...
-
オブジェクト参照がオブジェク...
-
VB.NET getとsetの概念がわかり...
-
フォームの存在をチェックする方法
-
変数の参照でエラーが出てしま...
-
C# インスタンスの破棄
-
生成したインスタンスを削除す...
-
文字列を日付に変換でParseExce...
-
次の日本語の意味を教えて下さい
-
C#「オブジェクト参照が必要で...
-
SQLを連続発行する時の正しい(?...
-
「インスタンス」の意味をわか...
-
[Visual C#] 優先される処理に...
-
newしないインスタンス?実体化...
-
C#の構造体の開放のしかた
-
javaのクラスの作り方、エラー...
おすすめ情報