这个Java ByteBuffer的行为有解释吗? [英] Is there an explanation for the behavior of this Java ByteBuffer?
问题描述
我需要将数值转换为字节数组。例如,要将long转换为字节数组,我有这个方法:
I need to convert numerical values into byte arrays. For example, to convert a long to a byte array, I have this method:
public static byte[] longToBytes(long l) {
ByteBuffer buff = ByteBuffer.allocate(8);
buff.order(ByteOrder.BIG_ENDIAN);
buff.putLong(l);
return buff.array();
}
这很简单 - 花一点时间,分配一个可以容纳它的数组,然后把它丢进去无论 l
的值是什么,我都会得到一个8字节的数组,然后我可以按照预期处理和使用它。在我的例子中,我正在创建一个自定义二进制格式,然后通过网络传输它。
It's pretty straightforward - take a long, allocate an array that can hold it, and throw it in there. Regardless of what the value of l
is, I will get an 8 byte array back that I can then process and use as intended. In my case, I'm creating a custom binary format and then transmitting it over a network.
当我使用值773450364调用此方法时,我得到一个数组 [0 0 0 0 46 25 -22 124]
返回。我的代码也将字节数组转换回它们的数值:
When I invoke this method with a value of 773450364, I get an array [0 0 0 0 46 25 -22 124]
back. I have code that also converts byte arrays back into their numerical values:
public static Long bytesToLong(byte[] aBytes, int start) {
byte[] b = new byte[8];
b[0] = aBytes[start + 0];
b[1] = aBytes[start + 1];
b[2] = aBytes[start + 2];
b[3] = aBytes[start + 3];
b[4] = aBytes[start + 4];
b[5] = aBytes[start + 5];
b[6] = aBytes[start + 6];
b[7] = aBytes[start + 7];
ByteBuffer buf = ByteBuffer.wrap(b);
return buf.getLong();
}
当我将数组从其他方法传回到此方法时,我得到了773450364,这是正确的。
When I pass the array from the other method back into this method, I get 773450364, which is correct.
现在,我通过TCP将此数组传输到另一个Java客户端。 java.io.InputStream.read()
方法的文档说它返回0到0之间的 int
值。 255,除非到达流的末尾并返回-1。但是,当我使用它来填充字节数组时,我继续在接收端获得负值。我怀疑这与溢出有关(255的值不适合Java字节,所以当我把它放入字节数组时,它溢出并变为负数)。
Now, I transmit this array over TCP to another Java client. The documentation for the java.io.InputStream.read()
method says that it returns a int
value between 0 and 255, unless the end of the stream is reached and a -1 is returned. However, when I use it to populate a byte array, I continue to get the negative values on the receiving side. I suspect this has to do with overflow (a value of 255 can not fit into a Java byte, so when I put it into the byte array, it overflows and becomes negative).
这让我想到了我的问题。负数的存在使我感到担忧。现在,我正在开发一个应用程序的Java端,其中一个字节介于-128和127之间。另一个端点可能是C,C ++,Python,Java,C#......谁知道。我不确定某些字节数组中负值的存在会如何影响处理。 除了记录这种行为之外,我可以/应该做些什么来使自己和未来的开发人员更容易在这个系统上工作,特别是在非Java编写的端点中?
This brings me to my problem. The existance of the negative numbers concerns me. Right now, I'm developing the Java side of an application, where a byte is between -128 and 127 inclusive. The other endpoint might be in C, C++, Python, Java, C#...who knows. I'm not sure how the existance of a negative value in some byte arrays are going to affect processing. Other than documenting this behavior, what can/should I do to make it easier for myself and future developers working on this system, especially in endpoints that are not written in Java?
推荐答案
Java中的字节
以8位两种补充格式。如果你有一个 int
,它在128 - 255范围内并且你将它转换为字节
,那么它将会成为字节
,带负值(介于-1和-128之间)。
A byte
in Java is represented in 8-bit two's complement format. If you have an int
that is in the range 128 - 255 and you cast it to a byte
, then it will become a byte
with a negative value (between -1 and -128).
读完一个字节后,你在将其转换为 byte
之前,必须检查它是否为-1 。该方法返回 int
而不是字节
的原因是允许您检查流末尾在将其转换为字节
之前。
After reading a byte, you must check if it is -1 before you cast it to byte
. The reason why the method returns an int
rather than a byte
is to allow you to check for end-of-stream before you convert it to a byte
.
另一件事:为什么要复制你的
数组?您可以大大简化该方法并保存不需要的副本: bytesToLong
方法中的aBytes
Another thing: Why are you copying the aBytes
array in your bytesToLong
method? You can simplify that method considerably and save the unncessary copy:
public static Long bytesToLong(byte[] aBytes, int start) {
return ByteBuffer.wrap(aBytes, start, 8).order(ByteOrder.BIG_ENDIAN).getLong();
}
这篇关于这个Java ByteBuffer的行为有解释吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!