Summary: I have a ByteBuffer in which I am pumping some data. After that, I want to send this data over a Socket.
So, I wrote code like this:
private static void serialize(ByteBuffer buffer, EmployeeData emp, CharsetEncoder encoder)
{
// id
buffer.putInt(emp.getId());
CharBuffer nameBuffer = CharBuffer.wrap(emp.getFirstName().toCharArray());
ByteBuffer nbBuffer = null;
// length of first name
try
{
nbBuffer = encoder.encode(nameBuffer);
}
catch(CharacterCodingException e)
{
throw new ArithmeticException();
}
System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getFirstName(), nbBuffer.limit()));
buffer.putInt(nbBuffer.limit());
buffer.put(nbBuffer);
// put lastname
nameBuffer = CharBuffer.wrap(emp.getLastName().toCharArray());
nbBuffer = null;
// length of first name
try
{
nbBuffer = encoder.encode(nameBuffer);
}
catch(CharacterCodingException e)
{
throw new ArithmeticException();
}
System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getLastName(), nbBuffer.limit()));
buffer.putInt(nbBuffer.limit());
buffer.put(nbBuffer);
// salary
buffer.putInt(emp.getSalary());
}
In the calling code, I do the following. I first get the serialized ByteBuffer and then write it out to the socket...
Socket client = new Socket("localhost", 8080);
OutputStream oStream = client.getOutputStream();
serialize(buffer, emp, encoder);
buffer.rewind();
while(buffer.hasRemaining())
{
byte temp = buffer.get();
++ written;
}
buffer.rewind();
System.out.println("#Bytes in output buffer: " + written + " limit = " + buffer.limit() + " pos = " + buffer.position() + " remaining = " + buffer.remaining());
int remaining = buffer.remaining();
while(remaining > 0)
{
oStream.write(buffer.get());
-- remaining;
}
I am expecting that buffer.remaining() should be exactly equal to the #bytes I pumped into the buffer. However I am finding that it is not, it is always equal to 1024, which is the size of the underlying array of the buffer.
This is how I create the buffer...
Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
byte [] underlyingBuffer = new byte[1024];
ByteBuffer buffer = ByteBuffer.wrap(underlyingBuffer);
buffer.order(ByteOrder.LITTLE_ENDIAN);
This is what I get as the output of my print statement...
String [John] #bytes = 4 String [Smith] #bytes = 5
#Bytes in output buffer: 1024 limit = 1024 pos = 0 remaining = 1024
How can I get the exact #bytes that were put into the buffer?
Thanks!
When you are done putting bytes into the buffer, you should flip
it. You can probably do this in place of your first call to rewind
instead.
A java.nio.Buffer
distinguishes between capacity
and limit
. If you don't flip it, then limit and capacity are the same as the length of the array with which you initialized it.
By flipping it, the limit will be set to the end of the data you've encoded, and capacity will still be 1024. ByteBuffer#remaining
looks at the delta between position and limit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With