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

3
我需要将Android应用中大小为4的byte[]转换为长整型。我找到了一个在java.io.Bits包中的函数byteArrayToLong(byte_array),但它在我的应用程序中无法正常工作。
是否有其他可替代的函数?
5个回答

2
使用 java.nio.ByteBuffer
byte[] data = new byte[] {50, -106, 40, -22};
ByteBuffer buffer = ByteBuffer.wrap(data);
System.out.println(buffer.getLong());

编辑

当然,@Kaito是正确的:你需要一个8字节的数组。另外,正如其他人提到的,你可以选择读取字节的顺序(默认为BIG_ENDIAN):

    byte[] data = new byte[] {50, -106, 40, -22, 0, 0, 0, 0};
    ByteBuffer buffer = ByteBuffer.wrap(data);
    buffer.order(ByteOrder.BIG_ENDIAN);
    System.out.println(buffer.getLong()); // 3645145933890453504
    buffer = ByteBuffer.wrap(data);
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    System.out.println(buffer.getLong()); // 3928528434

此外,为什么要使用API方法?出于简单性的考虑:您可以阅读这里发生的事情的纯英语,而不是在位移中识别字节到长整型的转换。

2
答案取决于你的第一个字节是最高有效字节还是最低有效字节。 如果第一个字节是最高有效字节:
long val = 0;

for (int i = 0; i < YourByte.length; i++)
{
   val = (val << 8) + (YourByte[i] & 0xff);
}

如果第一个字节是最低有效字节:

long val = 0;

for (int i = 0; i < YourByte.length; i++)
{
   val += ((long) YourByte[i] & 0xffL) << (i*8);
}

编辑:

在处理超过8个字节的数据时,请使用BigInteger而不是long


我刚从Kaito的回答中意识到,如果你需要处理超过8个字节的数据,你可以使用BigInteger而不是long。 - THE DOCTOR

2
医生的回答是正确的,但我会去掉循环。
对于小端序(最可能的情况):
long val = b[0] | ((int)(b[1]) << 8) | ((int)(b[2]) << 16) | ((int)(b[3]) << 24);

对于大端字节序:

long val = b[3] | ((int)(b[2]) << 8) | ((int)(b[1]) << 16) | ((int)(b[0]) << 24);

另外要记住,Java中的 long 类型长度为8字节。如果只需要4字节,则 int 类型已足够。


另一件我想到的事情是先将字节数组转换为字符串类型,然后使用解析方法将其转换回长整型。目前我正在尝试这种方法,但遇到了一些错误,也不确定它是否有效。 - user1362653
如果你问这样的问题 - 是行不通的。涉及到获取ASCII表示太麻烦了。 - Seva Alekseyev
是的,我也有同样的疑问,现在我正在使用ANDREY的答案,它很好地解决了我的问题。 - user1362653
一个Int可能不够用。Java仅支持有符号数,因此无符号的4字节int可能无法适应Java的Int。 - Kaito
对我来说,小端模式只能这样工作: long val = (b[0] & 0xff) | ((b[1] & 0xff) << 8) | ((b[2] & 0xff) << 16) | ((b[3] & 0xff) << 24) - Michele Bontorno

1

有三个选项:

  1. 将数组传递给BigInteger构造函数,然后从BigInteger获取long值
  2. 使用另外4个字节填充数组,并使用ByteBuffer.wrap,然后获取Long值
  3. 通过将每个字节移动到正确位置来手动构造它。

根据字节顺序,您可能需要反转数组。


你能展示一下你会如何处理第一个选项吗? - user1362653
new java.math.BigInteger(new byte[] {0,0,0,1}).longValue() - Kaito

0

当将长度小于8个字节的byte[ ]转换为long类型时:

public static ByteBuffer byteArraytoByteBuffer(int capacity,byte[] array) { ByteBuffer buffer = ByteBuffer.allocate(capacity).put(array).order(ByteOrder.LITTLE_ENDIAN); buffer.rewind(); return buffer; }

然后

byte[] input = new byte[]{1,0,0,0};
long value = byteArraytoByteBuffer(8,input).getLong();

1. ByteBuffer.allocate(capacity) 分配了8字节以存储long类型。

buffer = {0,0,0,0,0,0,0,0}

2. put(array) 将4个字节放入buffer中

buffer = {1,0,0,0,0,0,0,0}

           ^
           |

现在缓冲区的位置是4

3.字节顺序可以根据需求为LITTLE_ENDIANBIG_ENDIAN

4.buffer.rewind()将缓冲区倒回并将位置设置为零,

缓冲区 = {1,0,0,0,0,0,0,0}

       ^
       |

如果没有执行buffer.rewind()操作,将会发生缓冲区下溢。因为位置在4处,当调用getLong()时,它将以4作为起始索引。
相同的代码可以用于将byte[]转换为int。 byte[] input = new byte[]{1,0,0,0};
long value = byteArraytoByteBuffer(4,input).getInt();

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