6

The java.nio.ByteBuffer class has a ByteBuffer.array() method, however this returns an array that is the size of the buffer's capacity, and not the used capacity. Due to this, I'm having some issues.

I have a ByteBuffer which I am allocating as some size and then I am inserting data to it.

ByteBuffer oldBuffer = ByteBuffer.allocate(SIZE);
addHeader(oldBuffer, pendingItems);
newBuffer.flip();
oldBuffer.put(newBuffer);
// as of now I am sending everything from oldBuffer
send(address, oldBuffer.array());

How can I just send what is being used in oldBuffer. Is there any one liner to do this?

flash
  • 1,455
  • 11
  • 61
  • 132
  • It would be simpler to modify your `send()` method to either accept a length (and an offset) or to take the actual `ByteBuffer` as a parameter. You shouldn't be copying data around like this. – user207421 Mar 15 '18 at 00:27

2 Answers2

8

You can flip the buffer, then create a new array with the remaining size of the buffer and fill it.

oldBuffer.flip();
byte[] remaining = new byte[oldBuffer.remaining()];
oldBuffer.get(remaining);

Another way in a one liner with flip() and Arrays.copyOf

oldBuffer.flip();
Arrays.copyOf(oldBuffer.array(), oldBuffer.remaining());

And without flip()

Arrays.copyOf(oldBuffer.array(), oldBuffer.position());

Also like EJP said, if you have access to the send(..) method, you can add a size and offset argument to the send() method, and avoid the need to create and fill a new array.

Jose Da Silva Gomes
  • 3,814
  • 3
  • 24
  • 34
  • yes I do have access to `send` method so what changes we can do their? can you provide an example on that just to make myself clear? – flash Mar 15 '18 at 00:47
  • Well that depends on how you handle the data in the `send` method, if you eventually will need the array of that length, you can do it this way and just call the `send(..)` method and without modifing anything. Also if the data is not that much you can just copy the array. – Jose Da Silva Gomes Mar 15 '18 at 00:52
  • Yes I do need byte array in that send method of that length. Also what is the difference between `with flip() version` vs `without flip() version`? – flash Mar 15 '18 at 00:54
  • Well if sooner or later you'll need the array of that length, so you can do it sooner. `Flip()` changes the limit, position and mark values of the `ByteBuffer`, is normally used before reading. The array is the same, so practically not much a difference, and if you aren't going to use that buffer anymore, there is no difference at all. – Jose Da Silva Gomes Mar 15 '18 at 00:59
2

The position() of the buffer indicates that the amount of used data in the buffer.

So create a byte array of that size.

Next go to the position 0 of the buffer, since you have to read data from there. rewind() does this.

Then use the get() method to copy the buffer data into the array.

byte[] data = new byte[buffer.position()];
buffer.rewind();
buffer.get(data);

Also note that buffer.array() works only if the buffer.hasArray() returns true. So check for hasArray()before calling it. Otherwise, buffer.array() will throw any of the following exception.

  1. UnsupportedOperationException - when calling it on direct buffer.
  2. ReadOnlyBufferException - if the buffer is read-only.
JavaTechnical
  • 8,846
  • 8
  • 61
  • 97