如何在Java中将字节转换为long?

我正在从硬件设备读取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; } 

对于字节序,用你知道的一些数字进行测试,然后你将使用字节移位将它们移动到long中。

您可能会发现这是一个起点。 http://www.janeg.ca/scjp/oper/shift.html

困难在于取决于结束性将改变你的方式,但是你会移动24,16,8然后加上最后一个,基本上,如果做32位,但你要更长,所以只需做额外的移位。

根据数据的字节顺序移动字节非常简单。 但是, long数据类型有一个小技巧,因为对int或更小的整数类型的二进制操作会将操作数提升为int 。 对于大于31位的左移,这将导致零,因为所有位都已移出int范围。

因此,通过在计算中包含long操作数来强制推广。 下面,我通过使用值0xFF L掩盖每个字节来做到这一点,这是一个long ,强制结果为long

 byte[] buf = new byte[8]; /* Fill buf somehow... */ long l = ((buf[0] & 0xFFL) << 56) | ((buf[1] & 0xFFL) << 48) | ((buf[2] & 0xFFL) << 40) | ((buf[3] & 0xFFL) << 32) | ((buf[4] & 0xFFL) << 24) | ((buf[5] & 0xFFL) << 16) | ((buf[6] & 0xFFL) << 8) | ((buf[7] & 0xFFL) << 0) ; 

我相信你可以从使用java.nio中受益。 这是你如何在一个长的存储8个字节:

 // Byte Array TO Long public static long batol(byte[] buff) { return batol(buff, false); } public static long batol(byte[] buff, boolean littleEndian) { assert(buff.length == 8); ByteBuffer bb = ByteBuffer.wrap(buff); if (littleEndian) bb.order(ByteOrder.LITTLE_ENDIAN); return bb.getLong(); } 

当然,生成的long将具有签名表示,但它们将具有与源数据相同的二进制值。 对于64位+无符号表示和算术,您需要使用BigInteger。 以下是如何将存储在long中的“unsigned”数据转换为正确的BigInteger:

 // "Unsigned" Long TO Big Integer public static BigInteger ultobi(long ul) { byte[] buff = new byte[8]; ByteBuffer.wrap(buff).asLongBuffer().put(ul); return new BigInteger(+1, buff); } 

字节#longValue()应该这样做

如果没有(感谢源代码示例),您可以使用java.nio.ByteBuffer等

  public static long toLong(byte[] b) { ByteBuffer bb = ByteBuffer.allocate(b.length); bb.put(b); return bb.getLong(); } 

最初的订单是BIG_ENDIAN,你可以在这里更多的芦苇

看一下BigInteger(byte [])。 它几乎是你想要的,除了它是一个签名的。 因此,在将其传递给BigInteger之前,您可以再添加一个字节。

另一件事是你应该知道你的字节是什么字节序。

希望这可以帮助。

如果您正在读取InputStream ,您可能还想查看DataInputStream.readLong() 。 Java 1.5引入了Long.reverseBytes(long) ,它可以帮助你获得字节序。

您可以使用:

 byte bVal = 127; Long longVar = Long.valueOf(bVal); 
 ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.getLong(); 
  public static long convertToLong(byte[] array) { ByteBuffer buffer = ByteBuffer.wrap(array); return buffer.getLong(); }