SocketChannelからBlockBufferにBLOCKSIZE(たとえば512)バイトのブロックを連続的に読み取ります。私はバイト[]にByteBufferのコンテンツを追加して、次のラウンドに行きたいと思います。結果は、SocketChannelから読み取られたすべてのバイトを含むbyte []になります。ByteBufferからbyte []への書き込みはbyte []に書き込みません
これでSystem.arraycopy(...)が正常に動作します。しかし、私がByteBufferのget(result、offset、length)を使うと、何も書き込まれません。結果の配列値はゼロのままです。
なぜですか?
public final static int BLOCKSIZE = 512;
public byte[] getReceivedData() {
int offset = 0, read;
byte[] result = {};
ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE);
try {
while (true) {
read = _socketChannel.read(buffer);
if (read < 1) {
// Nothing was read.
break;
}
// Enlarge result so we can append the bytes we just read.
result = Arrays.copyOf(result, result.length + read);
// This works as expected.
System.arraycopy(buffer.array(), 0, result, offset * BLOCKSIZE, read);
// With this, however, nothing is written to result. Why?
buffer.get(result, offset * BLOCKSIZE, read);
if (read < BLOCKSIZE) {
// Nothing left to read from _socketChannel.
break;
}
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
EDIT:
私も、offset++
が欠落していた気づきました。だから、BLOCKSIZE
バイト以上がチャンネルに残っていると、事態が悪くなってしまいます...
とにかく、ByteArrayOutputStream
は本当に簡単になりますので、私はそれを使用することにしました。
の作業コード:
public byte[] getReceivedData() {
int read;
ByteArrayOutputStream result = new ByteArrayOutputStream();
ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE);
try {
while (true) {
buffer.clear();
read = _socketChannel.read(buffer);
if (read < 1) {
break;
}
result.write(buffer.array(), 0, read);
if (read < BLOCKSIZE) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return result.toByteArray();
}
フリップ()は、トリックをしました、ありがとう。私は 'compact()'は必要ないと思う。バッファからすべてのものを 'get()'した後、コンパイルする必要はありませんし、とにかく各繰り返しで 'clear()'します。また、チャンネルを閉じるヒントをありがとう。私はチャンネルが開いたままであることを意識しています。クライアントはいつでも新しいデータを送信できます。 – riha
@riha間違っています。あなたが-1を取得した後でクライアントはあなたにそれ以上のデータを送るつもりはありません。これはチャネル上のストリームの終わりであり、ピアが接続を閉じたこと、または少なくとも出力のためにシャットダウンしたことを意味します。それを閉じます。 – EJP
ええ、それは本当に私の側でも閉じなければなりません。それは決して私の場合に起こるはずはないが、それは別の話だ。再度、感謝します。 – riha