Search code examples
javac#binarymemorystreambytebuffer

Translating from Java to C# a snippet of ByteBuffer code


I've been trying to translate the following Java code to C#.

    // two bytes to make a short (16 bit integer)
private short bytesToShort(byte hi, byte low) {
    return ByteBuffer.wrap(new byte[]{hi, low}).getShort();
}

So far this is what I've managed to put together from searching around:

    private short bytesToShort(byte hi, byte low)
{
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream);

    writer.Write(hi);
    writer.Flush();
    writer.Write(low);
    writer.Flush();

    BinaryReader reader = new BinaryReader(stream);
    
    return reader.ReadInt16();
    
}

But I'm getting the "Unable to read beyond the end of stream" error. Adding stream.Position = 0; after the last writer.Flush(); fixes that issue but the values I'm getting are not correct. I assume I have more issue with the above code and the stream.Position = 0; is not the correct answer even if it seems to fix the issue.

Any suggestions?

UPDATE

I have two working solutions to this now. The first one is what Andreas posted as an answer below:

return (short) (((hi & 0xFF) << 8) | (low & 0xFF));

It works like a charm and I think out of the two solutions I have, this is the better one. The other is:

return BitConverter.ToInt16(new byte[2] { (byte)low, (byte)hi }, 0);

For this one I had to swap the positions of "low" and "hi" in order to get the correct results.

Important! For those translating from Java to C#, there is a very important difference between the Java byte and the C# byte.

Java byte is signed which means it takes values between -128 to 127 but the C# byte is unsigned which takes values between 0 and 255.

If you want to use the Java signed byte in C#, you have to use sbyte, this was a detail I was not aware off and it created issues for me.


Solution

  • return ByteBuffer.wrap(new byte[]{hi, low}).getShort() is the same as:

    return (short) (((hi & 0xFF) << 8) | (low & 0xFF));
    

    That version is the same in both Java and C#.