I’m consecutively reading blocks of BLOCKSIZE (e.g. 512) bytes from a SocketChannel into a ByteBuffer. I’d then like to append the ByteBuffer content to a byte[] and go for the next round. The result would be a byte[] containing all the bytes that were read from the SocketChannel.
Now, System.arraycopy(…) works as expected. But when I use ByteBuffer’s get(result, offset, length), nothing is written. The result array values remain zeroed.
Why is that?
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:
I noticed offset++ was missing, too. So if there is more than BLOCKSIZE bytes on the channel, things get messed up…
Anyways, ByteArrayOutputStream really makes things simpler there so I decided to use that.
Working code:
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();
}
You need to
flip()the buffer before theget(), andcompact()it afterwards.If
read == -1you need to not only break out of the loop but close the channel too.