Search code examples
javanioencodebytebuffer

Writing mixed data type in a ByteBuffer


Good morning. I need to store data with the following format in a ByteBuffer. This ByteBuffer is then stored and later printed to console.

Data Format:

10:30             [2]                 This is my message to you.
IntCharInt  Char  CharIntChar  Char   String

The storing part looks straightforward.

ByteBuffer buff = ByteBuffer.allocate(100);

buffer.putInt(10).putChar(':').putInt(30).putChar(' ');
buffer.putChar('[').putInt(2).putChar(']').putChar(' ');
buffer.put("This is my message to you.".getBytes());

I can retrieve the underlying byte array by doing:

byte[] bArray = buff.array( );

How do I encode the bArray in a string such that it is equal to the original string (by value-equality)?

Many Thanks


Solution

  • Here's how you can do it. Note that it works fine because the String is the last thing you wrote, so you know it goes from the after the last written char to the last written position of the buffer. If it was in the middle, you would have to somehow write the length of the string to be able to know how many bytes to read.

        ByteBuffer buffer = ByteBuffer.allocate(100);
    
        buffer.putInt(10).putChar(':').putInt(30).putChar(' ');
        buffer.putChar('[').putInt(2).putChar(']').putChar(' ');
    
        // use a well-defined charset rather than the default one, 
        // which varies from platform to platform
        buffer.put("This is my message to you.".getBytes(StandardCharsets.UTF_8));
    
        // go back to the beginning of the buffer
        buffer.flip();
    
        // get all the bytes that have actually been written to the buffer
        byte[] bArray = new byte[buffer.remaining()];
        buffer.get(bArray);
    
        // recreate a buffer wrapping the saved byte array
        buffer = ByteBuffer.wrap(bArray);
        String original =
            new StringBuilder()
                .append(buffer.getInt())
                .append(buffer.getChar())
                .append(buffer.getInt())
                .append(buffer.getChar())
                .append(buffer.getChar())
                .append(buffer.getInt())
                .append(buffer.getChar())
                .append(buffer.getChar())
                .append(new String(buffer.array(), buffer.position(), buffer.remaining(), StandardCharsets.UTF_8))
                .toString();
        System.out.println("original = " + original);