Converting raw-byte values into Java types
I have a problem with converting raw-bytes values into java types. I am receiving bytes by a datagram socket as a bytes array. I know exactly which bytes means what, but I don't know how to convert them appropriately (I mean I know offsets, but don't know if what I think I received is correct ;)).
For example, I want to convert 16 bit unsigned short into java int type. I found some examples开发者_开发百科 in the web, the one is:
public int getUShort(byte[] bytes, int offset) {
int b0 = bytes[offset] & oxFF;
int b1 = bytes[offset + 1] & oxFF;
return (b1 << 8) + (b0 << 0);
Another one is the same but the last line is:
return (b0 << 8) + b1;
Of course it gives different results. Which one is correct? Can you please give me also a valid example how to do the same but for an unsigned long?
Thank you in advance!
I had to do some work similar to this a while back and I found that the best way to do this sort of work is to use ByteBuffer
and its conversions to DoubleBuffer
, LongBuffer
, etc. You can convert an array of bytes into a ByteBuffer
by calling
ByteBuffer myBuffer = ByteBuffer.wrap(myRawArray);
From there, you can get a view of the bytes as a list of int
s by calling
IntBuffer myIntBuffer = myBuffer.asIntBuffer();
and you can then convert the bytes by calling
int nextInt = myIntBuffer.get();
These classes also have lots of support for bulk get operations, so if you know for a fact that you're receiving a whole bunch of data of the same type over the network you can do the conversions very quickly.
An alternative approach would be, if at all possible, to use some sort of Java-based serialization to send the data over the network. This allows you to do the conversions much more easily using the stream writer classes. Of course, this might not be available, especially if you're communicating with a non-Java server, but it might be worth exploring.
You can use DataInputStream or ByteBuffer to read the various types. You can use signed types as unsigned values for most operations just the same. I have written a simple class to illustrate how you can use the signed types as if they were unsigned Unsigned
ByteBuffer b = ByteBuffer.wrap(bytes);
short s = b.getShort();
long l = b.getLong();
Really late on this one.
Both are correct based on the endianess of the data. See here: http://en.wikipedia.org/wiki/Endianness
return (b1 << 8) + b0;//little endian
return (b0 << 8) + b1;//big endian
精彩评论