0

ファイルチャネルから別のファイルチャネルにファイルの一部をコピーしようとしています (実際には、新しいファイルを書き込むことは最初のファイルと同じです)。

だから、私は256kbのチャンクを読んでいて、それらを別のチャンネルに戻しています

static void openfile(String str) throws FileNotFoundException, IOException {
    int size=262144;
    FileInputStream fis = new FileInputStream(str);
    FileChannel fc = fis.getChannel();
    byte[] barray = new byte[size];
    ByteBuffer bb = ByteBuffer.wrap(barray);

    FileOutputStream fos = new FileOutputStream(str+"2" /**/);
    FileChannel fo = fos.getChannel();

    StringBuilder sb;
    while (fc.read(bb) != -1) {            
        fo.write(bb /**/);            
        bb.clear();
    }
}

問題は、(私が思うに) fo.write がチャネルの先頭から再度書き込むため、新しいファイルが最後に読み取られたチャンクのみで作成されることです。

試してみましfo.write (bb, bb.position())たが、期待どおりに機能しませんでした(ポインターはチャネルの先頭に戻りますか?)そしてFileOutputStream(str+"2", true)、新しいファイルの最後に追加されると考えていましたが、そうではありませんでした。

私は 256kb のチャンクで作業する必要があるので、プログラムの構造をあまり変更することはできません (何かひどく間違ったことをしていない限り)。


で解決bb.flip();

while (fi.read(bb) != -1) {
        bb.flip();
        fo.write(bb);
        bb.clear();
    }
4

2 に答える 2

0

これは非常に古い質問ですが、偶然見つけましたが、 FileChannel.transferToまたはFileChannel.transferFromを使用してパフォーマンスが向上する可能性がある別の回答を追加する可能性があります。javadocに従って:

この方法は、ソース チャネルから読み取り、このチャネルに書き込む単純なループよりもはるかに効率的である可能性があります。多くのオペレーティング システムは、バイトを実際にコピーせずに、ソース チャネルからファイル システム キャッシュに直接転送できます。

public static void copy(FileChannel src, FileChannel dst) throws IOException {
    long size = src.size();
    long transferred = 0;
    do {
        transferred += src.transferTo(0, size, dst);
    } while (transferred < size);
}

src.transferTo(0, src.size(), dst); ほとんどの場合、どのチャネルも非ブロッキングでない場合は単純に機能します。

于 2014-04-16T11:51:04.950 に答える