将两个字节读入一个整数?

30

我有一个从文件中读取的byte[],我想从其中的两个字节中获取一个int。以下是一个例子:

byte[] bytes = new byte[] {(byte)0x00, (byte)0x2F, (byte)0x01, (byte)0x10, (byte)0x6F};
int value = bytes.getInt(2,4); //This method doesn't exist

这应该使得 value 等于 0x0110,或者在十进制下等于 272。但是显然,byte[].getInt() 是不存在的。我该如何完成这个任务呢?
以上数组只是一个示例。实际值对我来说是未知的。

答案有效的原因是,如果这是导致你难以理解的原因,那么字节会被提升为整数。 "bytes [2] * 256" 不适合一个字节,但这不是问题,因为 "256" 是一个整数,等等。 - SyntaxT3rr0r
1
可能重复:将4个字节转换为整数 - finnw
6个回答

51

你只需要选择简单的:

int val = ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);

如果你不想让一堆计算散落在代码中,甚至可以编写自己的帮助函数getBytesAsWord(byte[] bytes, int start) 来提供这种功能,但我认为那可能会有点过度。


4
理想情况下应该是 (b1 << 8) | (b2 & 0x00ff)。 如果第二个字节的值大于128,上述转换将会得到错误的值,因为Java将该字节视为负整数。 - Gopi
为什么要使用 0xff?换句话说,与 bytes[0] << 8 | bytes[1] 相比有什么区别? - arve0

6

尝试:

public static int getInt(byte[] arr, int off) {
  return arr[off]<<8 &0xFF00 | arr[off+1]&0xFF;
} // end of getInt

您的问题没有说明两个参数(2,4)的含义。在您的示例中,2和4作为查找ox01和0x10数组中的索引是没有意义的,我猜您想要取两个连续的元素,这是一个常见的操作,因此我在我的方法中使用了off和off+1。
在Java中,您无法扩展byte[]类,因此您无法拥有一个名为bytes.getInt的方法,因此我制作了一个静态方法,它使用byte[]作为第一个参数。
该方法的“技巧”在于,您的字节是8位有符号整数,超过0x80的值是负数,并且会进行符号扩展(即在用作int时变为0xFFFFFF80)。这就是为什么需要“&0xFF”掩码的原因。"<<8"将更高位的字节左移8位。"|"将两个值组合起来——就像"+"一样。运算符的顺序很重要,因为<<具有最高优先级,其次是&,然后是|——因此不需要括号。

谢谢您的详细解释。对于有符号值的相同操作,我使用了:return arr[off]<<8 | arr[off+1]&0xFF; - Daniel Alder

6
这是一个简单而可靠的方法。
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4);
    // by choosing big endian, high order bytes must be put
    // to the buffer before low order bytes
    byteBuffer.order(ByteOrder.BIG_ENDIAN);
    // since ints are 4 bytes (32 bit), you need to put all 4, so put 0
    // for the high order bytes
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x01);
    byteBuffer.put((byte)0x10);
    byteBuffer.flip();
    int result = byteBuffer.getInt();

1

或者,您可以使用:

int val = (bytes[2] << 8) + bytes[3]

3
不会:如果bytes [2]大于0x7f,则它将返回负整数。需要来自paxdiablo答案的“&0xff”。 - Francois

0
你可以使用 ByteBuffer。它有你正在寻找的 getInt 方法和许多其他有用的方法。

0

Google Base16类来自Guava-14.0.1。

new BigInteger(com.google.common.io.BaseEncoding.base16().encode(bytesParam),16).longValue();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接