如何在Java中将字节数组转换为长整型?

7
我正在从硬件设备中读取8个字节的数据,需要将它们转换为数字值。我想将它们转换为长整型,因为这应该可以适配8个字节。我不太熟悉Java和低级数据类型操作。我似乎有两个问题(除了事实上几乎没有关于相关硬件的文档),这些字节期望是无符号的,所以我不能进行简单的整数转换。我不确定它们的字节序。

如果有任何建议,都非常感激。


最终采用了以下代码(来自我可能应该一周前就阅读的一些源代码):

public static final long toLong (byte[] byteArray, int offset, int len)
{
   long val = 0;
   len = Math.min(len, 8);
   for (int i = (len - 1); i >= 0; i--)
   {
      val <<= 8;
      val |= (byteArray [offset + i] & 0x00FF);
   }
   return val;
}

1
为什么需要将这8个字节转换为单个数字值?如果它们确实是较大值的组成字节,则它们既不是“有符号”也不是“无符号”。如果您不知道它们的字节序,那么您就不能将它们解释为某个长整型值。 - Jonathan Feinberg
我知道它们是连续的值(磁计数器),所以通过试错法,我可以找到它何时报告正确的递增。我需要将它们转换为单个数字值,以确定其变化率。 - Jotham
你应该将0x00FF替换为0xFFL,因为这样更能表达你将一个字节转换为长整型的意图。 - starblue
当你说“最终得到了这个结果”时,我觉得它似乎与 Erickson 的答案不一致,而他的答案是正确的。 - dfrankow
11个回答

0
下面的代码将字节解析为任意长度≤8的有符号数字。
static long bytesToSignedNumber(boolean reverseOrder, byte... bytes) {
    if (bytes.length > 8) bytes = Arrays.copyOfRange(bytes, 0, 8); //delete this line to ignore the higher excess bytes instead of the lower ones

    int l = bytes.length;
    long number = 0;
    for (int i = 0; i < l; i++) {
        long current;
        if (l==3 || l==5 || l==6 || l==7 //delete this line if you want to operate with 3,5,6,7-byte signed numbers (unlikely)
                || !reverseOrder && (i > 0)
                || reverseOrder && (i < l-1)) {
            current = ((long) bytes[i]) & 0x0000_0000_0000_00ff; //unsigned
        } else {
            current = (long) bytes[i];                           //signed
        }
        if (reverseOrder) number += current << (8 * i);
        else number = (number << 8) + current;
    }

    return number;
}

它将字节数组解析为最小现有类型的数字,并转换为long。以下是一些示例:

bytesToSignedNumber(false, 0x01, 0x04) 返回 260(2个字节作为short

bytesToSignedNumber(false, 0xF1, 0x04) 返回 -3836(2个字节作为short

bytesToSignedNumber(false, 0x01, 0x01, 0x04) 返回 65796(3个字节作为int

bytesToSignedNumber(false, 0xF1, 0x01, 0x04) 返回 15794436(3个字节作为int

bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x04) 返回 -251592444(4个字节作为int

bytesToSignedNumber(false, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04) 返回 1081146489369067777(其中8个字节为long长整型)。


这是最全能的算法,可以针对任何输入数据返回有意义的结果。 - antaki93

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