アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか?

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();

A 回答 (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 のバッファを組み合わせて使っても、別段悪影響が出るわけではありません。
    • good
    • 0

Javaにこだわらないならこういう方法もあります。


java.lang.Runtime,exec("copy sample1.data sample2.data");

まずボトルネックがどこかprofilerで計測してみては?
    • good
    • 0

>out.write(aa);


ではなくて
out.write(aa, 0, c);
です。
何故かはJavaDocを見て勉強して下さい。
    • good
    • 1

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();
}
}
}

   

補足日時:2006/03/30 01:53
    • good
    • 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());
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!