如何在 Java 中将字节转换为 long?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1586882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I convert a byte to a long in Java?
提问by Jotham
I am reading 8 bytes of data in from a hardware device. I need to convert them into a numeric value. I think I want to convert them to a long as that should fit 8 bytes. I am not very familiar with Java and low level data type operations. I seem to have two problems (apart from the fact there is almost no documentation for the hardware in question), The bytes are expecting to be unsigned, so I can't do a straight integer conversion. I am not sure what endianness they are.
我正在从硬件设备读取 8 个字节的数据。我需要将它们转换为数值。我想我想将它们转换为适合 8 个字节的 long。我对 Java 和低级数据类型操作不是很熟悉。我似乎有两个问题(除了几乎没有有关硬件的文档这一事实之外),字节期望是无符号的,因此我无法进行直接的整数转换。我不确定它们是什么字节序。
Any advice would be appreciated.
任何意见,将不胜感激。
Ended up with this (taken from some source code I probably should have read a week ago):
结束了这个(取自一些我可能应该在一周前阅读的源代码):
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;
}
采纳答案by James Black
For the endianness, test with some numbers you know, and then you will be using a byte shifting to move them into the long.
对于字节顺序,请使用您知道的一些数字进行测试,然后您将使用字节移位将它们移动到 long 中。
You may find this to be a starting point. http://www.janeg.ca/scjp/oper/shift.html
您可能会发现这是一个起点。 http://www.janeg.ca/scjp/oper/shift.html
The difficulty is that depending on the endianess will change how you do it, but you will shift by 24, 16, 8 then add the last one, basically, if doing 32 bits, but you are going longer, so just do extra shifting.
困难在于,根据字节顺序会改变您的操作方式,但是您将移位 24、16、8,然后添加最后一个,基本上,如果执行 32 位,但您要更长的时间,所以只需进行额外的移位。
回答by Bostone
Byte#longValue()should do it
Byte#longValue()应该这样做
And if not (thanks for the source example) you can use java.nio.ByteBuffer such as in
如果没有(感谢源示例),您可以使用 java.nio.ByteBuffer 例如
public static long toLong(byte[] b) {
ByteBuffer bb = ByteBuffer.allocate(b.length);
bb.put(b);
return bb.getLong();
}
The initial order is BIG_ENDIAN you can reed more here
最初的订单是 BIG_ENDIAN 你可以在这里了解更多
回答by NawaMan
Take a look at BigInteger(byte[]). It is almost what you want except that it is a signed one. So you may add one more byte to it before you pass it on to BigInteger.
看看 BigInteger(byte[])。除了它是签名的之外,这几乎就是您想要的。因此,您可以在将其传递给 BigInteger 之前再添加一个字节。
Another thing is that you should be aware of what endian your bytes are.
另一件事是你应该知道你的字节是什么字节序。
Hope this helps.
希望这可以帮助。
回答by erickson
Shifting bytes according to the endianness of the data is fairly straightforward. There is a small trick with the long
datatype, however, because a binary operation on integral types of int
or smaller promotes the operands to int
. For left shifts larger than 31 bits, this will result in zero, since all of the bits have been shifted out of the int
range.
根据数据的字节序移动字节相当简单。long
然而,数据类型有一个小技巧,因为对整数类型int
或更小的二元运算将操作数提升为int
。对于大于 31 位的左移,这将导致零,因为所有位都已移出int
范围。
So, force promotion to long
by including a long
operand in the calculation. Below, I do this by masking each byte with the value 0xFFL, which is a long
, forcing the result to be a long
.
因此,long
通过long
在计算中包含一个操作数来强制提升。下面,我通过用值 0xFF L屏蔽每个字节来做到这一点,它是 a long
,强制结果为 a 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) ;
回答by Gunslinger47
I believe that you could benefit from using java.nio. This is how you can store 8 bytes in a long:
我相信您可以从使用 java.nio 中受益。这是您如何在 long 中存储 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();
}
Of course, the resulting longs will have signed representation, but they will have identical binary values to the source data. For a 64 bit+ unsigned representation and arithmatic, you'll need to use BigInteger. Here's how to convert from "unsigned" data stored in a long to a correct BigInteger:
当然,生成的 long 将具有带符号表示,但它们将具有与源数据相同的二进制值。对于 64 位 + 无符号表示和算术,您需要使用 BigInteger。以下是如何将存储在 long 中的“无符号”数据转换为正确的 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);
}
回答by McDowell
If you're reading from an InputStream
, you may also want to look at DataInputStream.readLong(). Java 1.5 introduced Long.reverseBytes(long)which may help you with endianness.
如果您正在阅读InputStream
,您可能还想查看DataInputStream.readLong()。Java 1.5 引入了Long.reverseBytes(long)可以帮助您处理字节序。
回答by akashdeep kashyap
You can use:
您可以使用:
byte bVal = 127;
Long longVar = Long.valueOf(bVal);
回答by Cork Kochi
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.getLong();
回答by Vicky
public static long convertToLong(byte[] array)
{
ByteBuffer buffer = ByteBuffer.wrap(array);
return buffer.getLong();
}