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

时间:2010-12-19 21:14:00

标签: java byte long-integer

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

14 个答案:

答案 0 :(得分:188)

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();
}

或者包装在类中以避免重复创建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();
    }
}

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

答案 1 :(得分:72)

您可以使用Byte conversion methods中的Google Guava

示例:

byte[] bytes = Longs.toByteArray(12345L);

答案 2 :(得分:69)

我针对普通的按位操作测试了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;
}

答案 3 :(得分:15)

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

我认为你的意思是 long 而不是 Long ,后者需要允许空值。

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

DataInputStream dis = new DataInputStream(
     new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();

答案 4 :(得分:10)

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

byte [] - &gt;长

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);

长 - &gt; 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)};

答案 5 :(得分:4)

只需将长号写入DataOutputStream,其中包含基础ByteArrayOutputStream。从ByteArrayOutputStream中,您可以通过toByteArray()获取字节数组:

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,您不需要手动使用字节[]。您将使用Socket socket及其流

OutputStream os=socket.getOutputStream(); 
DataOutputStream dos=new DataOutputStream(os);
dos.writeLong(l);
//etc ..

代替。

答案 6 :(得分:4)

您可以在org.apache.hadoop.hbase.util.Bytes http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/util/Bytes.html中使用该实现

源代码在这里:

http://grepcode.com/file/repository.cloudera.com/content/repositories/releases/com.cloudera.hbase/hbase/0.89.20100924-28/org/apache/hadoop/hbase/util/Bytes.java#Bytes.toBytes%28long%29

查找toLong和toBytes方法。

我相信软件许可证允许您使用部分代码并使用它,但请验证。

答案 7 :(得分:3)

 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;
    }

答案 8 :(得分:1)

如果您已经使用OutputStream写入套接字,那么DataOutputStream可能是合适的。这是一个例子:

// Assumes you are currently working with a SocketOutputStream.

SocketOutputStream outputStream = ...
long longValue = ...

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

dataOutputStream.writeLong(longValue);
dataOutputStream.flush();

shortintfloat等有类似的方法。然后您可以在接收方使用DataInputStream

答案 9 :(得分:1)

我将添加另一个可能最快的答案yes(是的,甚至超过接受的答案),但它不适用于每一个案例。但是,它适用于所有可能的场景:

您可以简单地使用String作为中间人。注意,即使看起来像使用String可能会产生错误的结果,因为你知道你正在使用“正常”字符串,这将给你正确的结果。这是一种提高效率并使代码更简单的方法,反过来必须对它所操作的数据字符串使用一些假设。

使用此方法的结论:如果您在ASCII表的开头使用某些ASCII字符(例如这些符号),则以下行可能会失败,但让我们面对它 - 您可能会反正从不使用它们。

使用此方法的专业人员:请记住,大多数人通常使用一些没有任何异常字符的普通字符串,然后该方法是最简单,最快捷的方法。

从Long到byte []:

byte[] arr = String.valueOf(longVar).getBytes();

从byte []到Long:

long longVar = Long.valueOf(new String(byteArr)).longValue();

答案 10 :(得分:1)

Long和ByteArray类型的Kotlin扩展:

fun Long.toByteArray() = numberToByteArray(Long.SIZE_BYTES) { putLong(this@toByteArray) }

private inline fun numberToByteArray(size: Int, bufferFun: ByteBuffer.() -> ByteBuffer): ByteArray =
    ByteBuffer.allocate(size).bufferFun().array()

@Throws(NumberFormatException::class)
fun ByteArray.toLong(): Long = toNumeric(Long.SIZE_BYTES) { long }

@Throws(NumberFormatException::class)
private inline fun <reified T: Number> ByteArray.toNumeric(size: Int, bufferFun: ByteBuffer.() -> T): T {
    if (this.size != size) throw NumberFormatException("${T::class.java.simpleName} value must contains $size bytes")

    return ByteBuffer.wrap(this).bufferFun()
}

您可以在我的图书馆here中看到完整的代码

答案 11 :(得分:0)

使用ByteBuffer.allocate(8).putLong(obj).array():

public byte[] toBytes(Long obj) {
    if (obj != null) {
      return ByteBuffer.allocate(8).putLong(obj).array();
    return null;
  }

来源:

对于ByteBuffer的许多其他用法示例:

答案 12 :(得分:0)

这是使用Java 8或更高版本将byte[]转换为long的另一种方法:

private static int bytesToInt(final byte[] bytes, final int offset) {
    assert offset + Integer.BYTES <= bytes.length;

    return (bytes[offset + Integer.BYTES - 1] & 0xFF) |
            (bytes[offset + Integer.BYTES - 2] & 0xFF) << Byte.SIZE |
            (bytes[offset + Integer.BYTES - 3] & 0xFF) << Byte.SIZE * 2 |
            (bytes[offset + Integer.BYTES - 4] & 0xFF) << Byte.SIZE * 3;
}

private static long bytesToLong(final byte[] bytes, final int offset) {
    return toUnsignedLong(bytesToInt(bytes, offset)) << Integer.SIZE |
            toUnsignedLong(bytesToInt(bytes, offset + Integer.BYTES));
}

转换long可以表示为两个整数值的高位和低位,这些位经过位或运算。请注意,toUnsignedLong来自Integer类,并且对toUnsignedLong的第一次调用可能是多余的。

相反的转换也可以展开,就像其他人提到的那样。

答案 13 :(得分:0)

我发现这种方法最友好。

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

var l = new BigInteger(b);