这个Java ByteBuffer的行为有解释吗?

Tho*_*ens 4 java byte bytebuffer bytearray inputstream

我需要将数值转换为字节数组.例如,要将long转换为byte数组,我有以下方法:

public static byte[] longToBytes(long l) {
  ByteBuffer buff = ByteBuffer.allocate(8);

  buff.order(ByteOrder.BIG_ENDIAN);

  buff.putLong(l);

  return buff.array();
}
Run Code Online (Sandbox Code Playgroud)

这很简单 - 花一点时间,分配一个可以容纳它的数组,然后把它扔进那里.无论价值l是多少,我都会得到一个8字节的数组,然后我可以按照预期进行处理和使用.就我而言,我正在创建一个自定义二进制格式,然后通过网络传输它.

当我使用值773450364调用此方法时,我得到一个数组[0 0 0 0 46 25 -22 124].我有代码也将字节数组转换回它们的数值:

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();
}
Run Code Online (Sandbox Code Playgroud)

当我将数组从另一个方法传递回此方法时,我得到773450364,这是正确的.

现在,我通过TCP将此数组传输到另一个Java客户端.该java.io.InputStream.read()方法的文档说它返回int0到255之间的值,除非到达流的末尾并返回-1.但是,当我使用它来填充字节数组时,我继续在接收端获得负值.我怀疑这与溢出有关(255的值不能适合Java字节,所以当我把它放入字节数组时,它会溢出并变为负数).

这让我想到了我的问题.负数的存在使我感到担忧.现在,我正在开发一个应用程序的Java端,其中一个字节介于-128和127之间.另一个端点可能是C,C++,Python,Java,C#......谁知道.我不确定某些字节数组中负值的存在会如何影响处理.除了记录这种行为之外,我可以/应该做些什么来使自己和未来的开发人员更容易在这个系统上工作,特别是在非Java编写的端点中?

Jes*_*per 6

byteJava中的A 以8位二进制补码格式表示.如果你int的范围在128 - 255之间并且你将其转换为a byte,则它将变为byte具有负值的值(在-1和-128之间).

读取一个字节后,必须在将其转换为之前byte检查它是否为-1 .该方法返回an int而不是a的原因byte是允许您在将其转换为a之前检查流末尾byte.

另一件事:为什么要aBytesbytesToLong方法中复制数组?您可以大大简化该方法并保存不必要的副本:

public static Long bytesToLong(byte[] aBytes, int start) {
    return ByteBuffer.wrap(aBytes, start, 8).order(ByteOrder.BIG_ENDIAN).getLong();
}
Run Code Online (Sandbox Code Playgroud)