riha
riha

Reputation: 2298

Get from ByteBuffer to byte[] does not write to byte[]

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();
  }

Upvotes: 0

Views: 1916

Answers (2)

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13535

Your result array is of length 0 and cannot hold any information. Byte arrays do not grow, and you are unable to append buffers' content. Use java.io.ByteArrayOutputStream to accumulate result.

Upvotes: 0

user207421
user207421

Reputation: 311039

You need to flip() the buffer before the get(), and compact() it afterwards.

If read == -1 you need to not only break out of the loop but close the channel too.

Upvotes: 2

Related Questions