如何在Java中将long
转换为byte[]
,并再次转换回来?
我正在尝试将long
转换为byte[]
,以便能够通过TCP连接发送byte[]
。 在另一端,我想将该byte[]
转换回long
。
如何在Java中将long
转换为byte[]
,并再次转换回来?
我正在尝试将long
转换为byte[]
,以便能够通过TCP连接发送byte[]
。 在另一端,我想将该byte[]
转换回long
。
public byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}
public long bytesToLong(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong();
}
或者将其包装在一个类中,以避免重复创建ByteBuffer:
public class ByteUtils {
private static ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
public static byte[] longToBytes(long x) {
buffer.putLong(0, x);
return buffer.array();
}
public static long bytesToLong(byte[] bytes) {
buffer.put(bytes, 0, bytes.length);
buffer.flip();//need flip
return buffer.getLong();
}
}
由于这篇文章变得如此流行,我想提一下,在绝大多数情况下,最好使用类似Guava这样的库。如果您对库有某种奇怪的反感,那么您可能应该先考虑这个答案来寻找本地Java解决方案。我认为我回答中的主要优点是您不必自己担心系统的字节序问题。我测试了使用ByteBuffer方法和使用位运算的效率,但是后者明显更快。
public static byte[] longToBytes(long l) {
byte[] result = new byte[8];
for (int i = 7; i >= 0; i--) {
result[i] = (byte)(l & 0xFF);
l >>= 8;
}
return result;
}
public static long bytesToLong(final byte[] b) {
long result = 0;
for (int i = 0; i < 8; i++) {
result <<= 8;
result |= (b[i] & 0xFF);
}
return result;
}
对于Java 8及以上版本,我们可以使用新增加的静态变量:
public static byte[] longToBytes(long l) {
byte[] result = new byte[Long.BYTES];
for (int i = Long.BYTES - 1; i >= 0; i--) {
result[i] = (byte)(l & 0xFF);
l >>= Byte.SIZE;
}
return result;
}
public static long bytesToLong(final byte[] b) {
long result = 0;
for (int i = 0; i < Long.BYTES; i++) {
result <<= Byte.SIZE;
result |= (b[i] & 0xFF);
}
return result;
}
Long.BYTES
是错误的。它不能传达意图,只是巧合起作用:Long.BYTES
是8。如果用Integer替换,它也会出错。相反,应该左移 Byte.SIZE
。 - Christian Hujer如果您正在寻找快速展开版本,只需使用以下代码即可,假设有一个长度为8的byte数组名为“b”:
byte[] -> long
long l = ((long) b[7] << 56)
| ((long) b[6] & 0xff) << 48
| ((long) b[5] & 0xff) << 40
| ((long) b[4] & 0xff) << 32
| ((long) b[3] & 0xff) << 24
| ((long) b[2] & 0xff) << 16
| ((long) b[1] & 0xff) << 8
| ((long) b[0] & 0xff);
long -> byte[]可作为上述内容的完全对应项。
byte[] b = new byte[] {
(byte) lng,
(byte) (lng >> 8),
(byte) (lng >> 16),
(byte) (lng >> 24),
(byte) (lng >> 32),
(byte) (lng >> 40),
(byte) (lng >> 48),
(byte) (lng >> 56)};
long -> byte[]
代码对于负数无效 :-/ - dnaultDataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
dos.writeLong(longValue);
DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();
byte[]
只是实现这个目的的一种手段。 - Ian McLairdByteBuffer
,根据文档的说法,“字节缓冲区的初始顺序始终为 BIG_ENDIAN(大端序)。” - David Phillips我觉得这种方法最友好。
byte[] b = BigInteger.valueOf(x).toByteArray();
long l = new BigInteger(b).longValue();
目前所有的回答都比必要的复杂,我不希望任何人在找到这个线程后没有更简洁的选项就离开。
你可以在一行代码中完成这两个转换。
byte[] 转 long:
ByteBuffer.wrap(yourBytes).getLong();
将long转换为byte[]:
ByteBuffer.wrap(new byte[8]).putLong(yourLong).array();
只需将长整型写入具有底层ByteArrayOutputStream的DataOutputStream中。通过toByteArray()方法,您可以从ByteArrayOutputStream获取字节数组:
class Main
{
public static byte[] long2byte(long l) throws IOException
{
ByteArrayOutputStream baos=new ByteArrayOutputStream(Long.SIZE/8);
DataOutputStream dos=new DataOutputStream(baos);
dos.writeLong(l);
byte[] result=baos.toByteArray();
dos.close();
return result;
}
public static long byte2long(byte[] b) throws IOException
{
ByteArrayInputStream baos=new ByteArrayInputStream(b);
DataInputStream dos=new DataInputStream(baos);
long result=dos.readLong();
dos.close();
return result;
}
public static void main (String[] args) throws java.lang.Exception
{
long l=123456L;
byte[] b=long2byte(l);
System.out.println(l+": "+byte2long(b));
}
}
相应地,适用于其他基元类型。
提示:对于TCP,您不需要手动使用byte[]。您将使用Socket socket
和其流。
OutputStream os=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
dos.writeLong(l);
//etc ..
请查找toLong和toBytes方法。
我相信软件许可证允许您使用代码的部分,请验证一下。
public static long bytesToLong(byte[] bytes) {
if (bytes.length > 8) {
throw new IllegalMethodParameterException("byte should not be more than 8 bytes");
}
long r = 0;
for (int i = 0; i < bytes.length; i++) {
r = r << 8;
r += bytes[i];
}
return r;
}
public static byte[] longToBytes(long l) {
ArrayList<Byte> bytes = new ArrayList<Byte>();
while (l != 0) {
bytes.add((byte) (l % (0xff + 1)));
l = l >> 8;
}
byte[] bytesp = new byte[bytes.size()];
for (int i = bytes.size() - 1, j = 0; i >= 0; i--, j++) {
bytesp[j] = bytes.get(i);
}
return bytesp;
}