如何将Long转换为byte []并返回java

Emr*_*801 139 java byte long-integer

如何将长转换为字节[]并返回Java?我正在尝试将long转换为byte [],以便我能够通过tcp连接发送byte [].另一方面,我想取该字节[]并将其转换回double.任何提示将不胜感激.

Bra*_*ace 205

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();
}
Run Code Online (Sandbox Code Playgroud)

或者包装在类中以避免重复创建ByteBuffers:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

由于这是如此受欢迎,我只想提一下,我认为你最好在绝大多数情况下使用像Guava这样的库.如果你对库有一些奇怪的反对意见,你应该首先考虑这个答案,首先是本机java解决方案.我认为我的答案最重要的是你不必担心系统的字节序本身.

  • 该实用程序方法不是线程安全的,所以我不确定它会好得多...... (32认同)
  • 在Java 8之前,您可以使用Long.SIZE/Byte.SIZE而不是Long.BYTES来避免幻数. (11认同)
  • 我认为这里的bytesToLong()会失败,因为put之后的位置是缓冲区的末尾,而不是开头.我想你会得到一个缓冲区下溢异常. (8认同)
  • 重复使用该bytebuffer是非常有问题的,而且不仅仅是出于其他人评论的线程安全性原因.中间不仅需要'.clear()',而且显而易见的是,在ByteBuffer上调用.array()会返回后备数组而不是副本.因此,如果您反复调用并保持其他结果,它们实际上是重复覆盖先前值的所有相同数组.以下评论中的hadoop链接是最高效的,可以避免任何这些问题. (6认同)
  • 聪明……但是您为每次转换创建并丢弃了一个临时 ByteBuffer。如果您为每条消息和/或大量消息发送多个 long 则不好。 (3认同)
  • @Stephen - 我只是做了足够的工作来演示如何使用 ByteBuffer,但我继续添加了一个在实用程序类中使用它的示例。 (2认同)
  • `bytesToLong` 方法还可以执行 `return ByteBuffer.wrap(bytes).getLong()` (2认同)

Son*_*123 80

您可以使用字节转换方法谷歌番石榴.

例:

byte[] bytes = Longs.toByteArray(12345L);
Run Code Online (Sandbox Code Playgroud)


Wyt*_*tze 75

我测试了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(byte[] b) {
    long result = 0;
    for (int i = 0; i < 8; i++) {
        result <<= 8;
        result |= (b[i] & 0xFF);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 幻数8应该在数组大小中定义为`Long.SIZE/Byte.SIZE`,在移位中定义为`Byte.SIZE`. (11认同)
  • 同意.我决定不让它离开这个例子.在Java 8中,您可以使用Long.BYTES而不是Long.SIZE/Byte.SIZE (7认同)
  • @Vipul按位 - 并且确实很重要,因为当执行`result | = b [i]`时,字节值将首先转换为long,这将执行符号扩展.值为-128(十六进制"0x80")的字节将变为长度,值为-128(十六进制"0xFFFF FFFF FFFF FF80").转换后的第一个是值或:ed在一起.使用bitwise-并通过首先将字节转换为int并切断符号扩展来防止这种情况:`(字节)0x80&0xFF ==>(int)0xFFFF FF80&0xFF ==>(int)0x80`.为什么字节在java中签名对我来说有点神秘,但我想它适合其他类型. (3认同)

Pet*_*rey 15

为什么需要byte []?为什么不把它写到套接字?

我假设你的意思是而不是,后者需要允许空值.

DataOutputStream dos = new DataOutputStream(
     new BufferedOutputStream(socket.getOutputStream()));
dos.writeLong(longValue);

DataInputStream dis = new DataInputStream(
     new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();
Run Code Online (Sandbox Code Playgroud)

  • 他问你如何转换为byte []并返回.很好的答案,但没有回答这个问题.你问为什么,因为你认为这是不必要的,但这是一个错误的假设.如果他在做跨语言或跨平台怎么办?DataOutputStream不会帮助你. (8认同)
  • 如果他正在进行跨语言或跨平台,那么以已知顺序发送字节非常重要.这个方法根据文档做到了(它将它们写成"高字节优先").接受的答案不是(根据文档将它们写入"当前顺序").问题表明他想通过TCP连接发送它们.`byte []`只是达到目的的一种手段. (4认同)
  • @IanMcLaird接受的答案确实使用已知的顺序.它创建了一个新的`ByteBuffer`,它根据文档_"字节缓冲区的初始顺序始终是BIG_ENDIAN._ (3认同)

Mic*_*ing 15

如果你正在寻找一个快速展开的版本,这应该可以做到这一点,假设一个名为"b"的字节数组长度为8:

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);
Run Code Online (Sandbox Code Playgroud)

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)};
Run Code Online (Sandbox Code Playgroud)

  • 这假设小端字节顺序,并且其他人在后续编辑中添加的“long -&gt; byte[]”代码对于负数失败:-/ (2认同)

jus*_*tis 12

目前所有的答案都比他们需要的更复杂,我讨厌任何找到这个线程的人在没有更简洁的选择的情况下就走开。

\n

您可以在一行中完成这两种转换。

\n

字节[]转长:

\n
ByteBuffer.wrap(yourBytes).getLong();\n
Run Code Online (Sandbox Code Playgroud)\n

长到字节[]:

\n
ByteBuffer.wrap(new byte[8]).putLong(yourLong).array();\n
Run Code Online (Sandbox Code Playgroud)\n


小智 6

我觉得这个方法最友好。

var b = BigInteger.valueOf(x).toByteArray();

var l = new BigInteger(b);
Run Code Online (Sandbox Code Playgroud)