Reading from and writing to a ByteBuffer
Once we've created a ByteBuffer, the first thing we probably
want to do is read or write some data to it.
Reading/writing a byte at the current position
The methods get() and put() read and write a byte respectively at the
current position and then automatically update the position.
Thus, in the simplest case of just wanting to read sequentially through data in the buffer
(or write data sequentially), this can be accomplished with some extremely straightforward code.
ByteBuffer bb = ByteBuffer.wrap(...);
byte b1 = bb.get(); // read the first byte
byte b2 = bb.get(); // read the second byte
A syntax reminder: if we're passing in a byte literal (that is,
where we just "hard code" a value in the code rather than passing a variable name), we
need to put an explicit cast:
Reading/writing at a particular offset
Supposing you don't want to read/write at the current position? Well, there are two
- calling the position() method, we can change the current position;
subsequent get()/put() operations will take place from there (but then still
updating the position each time as before);
- we can pass in an explicit offset to the get() and put() methods.
So for example, this line will write the byte 32 to position 140:
buff.put(140, (byte) 32);
Note that these offset-specific put() and get() operations don't move
the buffer's current position.
Reading/writing unsigned bytes
A slight complication in Java is that, perhaps contrary to common sense, the
byte data type is always signed. What that means is that if you
try and read/write the byte 128, when converted to a Java byte,
this will actually come out as -128; byte 129 will actually come
out as -127 etc. With some slightly klutzy code we can work round the problem:
- to write an unsigned byte, we hold or calculate the value as an int and
then simply cast to a byte;
- to read an unsigned byte, we make sure we are reading into an int
(or at least, something bigger than a byte), and then AND with 255 (0xff in hex).
This is what the latter code looks like:
int unsignedByte = bb.get() & 0xff;
This works because whenever you perform bitwise operations in Java, both operands
(the things either side of the &) are converted to (at least) an int. Initially, a negative
byte will be converted to a negative int (the sign is preserved or what is technically called sign extended).
Then, ANDing with 255 (the maximum positive number that can fit in an 8-bit byte) in effect "chops off" the
higher up bits that mark the int as negative.
Reading/writing other types
A key feature of a ByteBuffer is actually that you can efficiently write types
other than a byte. On the next page, we look at reading and
writing non-byte types in a ByteBuffer.