这个Java ByteBuffer的行为有解释吗? [英] Is there an explanation for the behavior of this Java ByteBuffer?

查看:242
本文介绍了这个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆