3

を使用してチャネルのI/O操作を実行したいByteBuffer。最後に、私は3つの解決策を思いつきました。

FileChannel inChannel = new FileInputStream("input.txt").getChannel();
FileChannel outChannel = new FileOutputStream("output.txt").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);

方法1:使用するhasRemaining()

while (inChannel.read(buf) != -1) {
    buf.flip();    
    while (buf.hasRemaining()) {
        outChannel.write(buf);
    }    
    buf.clear();
}

方法2:使用するcompact()

while (inChannel.read(buf) != -1 || buf.position() > 0) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}

方法3:ハイブリッドモデル

while (inChannel.read(buf) != -1) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}
// final flush of pending output
while (buf.hasRemaining())
    outChannel.write(buf);

問題は、どの方法が最もパフォーマンスとスループットが高いかということです。

4

2 に答える 2

3

compact()なぜあなたはまったく使いたいのですか?-大量のデータを繰り返しコピーする場合があります。

最初の方法は、以前に読み取ったすべてのデータが書き込まれる前に、別の読み取りを実行する重大な理由がない場合に実行する方法です。

ちなみに、あるファイルから別のファイルにデータをコピーするだけの場合は、、transferTo()またはを参照してくださいtransferFrom()。これは、ファイルコピーの最もパフォーマンスの高い方法です。これは、たとえばDMAなどの基盤となるOSの非常に効率的な操作を使用する可能性があるためです。

(編集:transferTo()などはもちろんByteBufferを必要とせず、そこに2つの考えが混在しています:))

于 2011-10-30T11:22:18.820 に答える
1

パフォーマンスを最大化するには、約32KBの直接バッファーを試すことをお勧めします。この16KBから64KBのサイズは、システムによっては多くの場合最適に機能します。

ファイルチャネルの場合、毎回すべてのデータを読み書きできるはずなので、さまざまな方法で違いはないと思います。ただし、ソケットチャネルへの読み取り/書き込み時に違いが生じる可能性があります。

于 2011-10-30T12:15:35.943 に答える