2

私はNIOを始めたばかりで、「ブロックベースの送信は一般的にストリームベースの送信よりも効果的です」という記事を見つけました。これは、read(ByteBuffer) がブロックベースの転送であり、read(byte[]) がストリームベースの転送であることを意味します。

2 つの方法の内部的な違いを知りたいです。

ps:ブロックベースの転送はバイト配列を転送し、ストリームベースの転送はバイトを 1 つずつ転送していると聞きました。java.io.FileInputStream.read(byte[]) もバイト配列を転送するため、間違っていると思います。

4

3 に答える 3

3

Bytebuffer をより効率的にする 1 つの方法は、ダイレクト メモリを使用することです。これにより、直接メモリから byte[] へのコピーが回避されます。あるチャネルから別のチャネルにデータをコピーするだけの場合、これは最大 30% 高速になります。バイトごとに読み取る場合、各バイトにアクセスするオーバーヘッドが増えるため、ByteBuffer を使用すると少し遅くなる可能性があります。たとえば、バイナリの読み取りに使用する場合、intまたはdouble1回のアクセスで値全体を取得できるため、はるかに高速になります。

于 2013-01-10T08:31:27.947 に答える
1

buffer-basedvs stream-basedI/O 操作について話していると思います。JavaNIOは、データが最初にバッファに読み込まれ、次に処理されるという意味でバッファ指向です。これにより、1 つの柔軟性が得られます。また、バッファを処理する前に、バッファに必要なデータがすべて含まれていることを確認する必要があります。一方、stream-basedI/O では、ストリームから 1 つ以上のバイトを読み取りますが、これらはどこにもキャッシュされません。これはブロッキング I/O であり、buffer-basedI/O (Java NIO) は非ブロッキング IO です。

于 2013-01-10T06:33:51.420 に答える
0

を特徴付けるために「ストリームベース」を使用するつもりはありませんが、場合によってはaよりread(byte[])も効率が向上します。ByteBufferbyte[]

ネットワーク I/O に Java NIO でダイレクト バッファを使用する必要がある場合の簡単なルールを参照してください。およびByteBuffer.allocate() 対 ByteBuffer.allocateDirect()

JVM が OS に渡したり、IO トリックを実行したりするのは (「直接」の場合)メモリ バッキングByteBufferがより簡単になり (たとえば、メモリを直接読み込んで書き込み呼び出しに渡す)、JVM の「オン」ではない可能性があります。ヒープ。a をバッキングするメモリbyte[]は JVM ヒープ上にあり、IO は通常、配列によって使用されるメモリに直接移動しません (代わりに、バウンス バッファを経由することがよくあります。または配列メモリが連続していない可能性があります)。

ただし、Java でデータを操作する必要がある場合は、データを操作するByteBufferために最終的にデータを Java ヒープにコピーする必要があるため、大きな違いはありません。操作なしでデータのコピーインとバックアウトを行っている場合は、直接 ByteBuffer が有利になる可能性があります。

于 2013-01-10T06:32:03.553 に答える