如何将长时间转换为字节[],然后返回java ?

时间:2022-09-15 18:58:55

How do I convert a long to a byte[] and back in Java? I'm trying convert a long to a byte[] so that I will be able to send the byte[] over a tcp connection. On the other side I want to take that byte[] and convert it back into a double. Any tips would be appreciated.

如何将长时间转换为字节[],然后返回Java?我正在尝试将一个长字节转换为一个字节[],这样我就能够通过tcp连接发送字节[]。在另一边,我想要把这个字节转换成double。任何提示都可以。

10 个解决方案

#1


153  

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

Or wrapped in a class to avoid repeatedly creating ByteBuffers:

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

Since this is getting so popular, I just want to mention that I think you're better off using a library like Guava in the vast majority of cases. And if you have some strange opposition to libraries, you should probably consider this answer first for native java solutions. I think the main thing my answer really has going for it is that you don't have to worry about the endian-ness of the system yourself.

既然这已经很流行了,我想说的是,我认为在绝大多数情况下使用像Guava这样的图书馆会更好。如果您对库有一些奇怪的反对意见,那么您应该首先考虑这个对原生java解决方案的回答。我认为我的答案最主要的是你不必担心系统本身的偶然性。

#2


57  

You could use the Byte conversion methods from Google Guava.

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

Example:

例子:

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

#3


49  

I tested the ByteBuffer method against plain bitwise operations but the latter is significantly faster.

我测试了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;
}

#4


12  

Why do you need the byte[]? why not just write it to the socket?

为什么需要字节[]?为什么不直接把它写在插座上呢?

I assume you mean long rather than Long, the latter needs to allow for null values.

我假设您的意思是long而不是long,后者需要允许null值。

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

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

#5


4  

You could use the implementation in org.apache.hadoop.hbase.util.Bytes http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/util/Bytes.html

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

The source code is here:

源代码在这里:

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

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 % 28长% 29

Look for the toLong and toBytes methods.

寻找toLong和toBytes方法。

I believe the software license allows you to take parts of the code and use it but please verify that.

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

#6


3  

Just write the long to a DataOutputStream with an underlying ByteArrayOutputStream. From the ByteArrayOutputStream you can get the byte-array via toByteArray():

只需将long写入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));       
        }
}

Works for other primitives accordingly.

为其他原语工作。

Hint: For TCP you do not need the byte[] manually. You will use a Socket socket and its streams

提示:对于TCP,您不需要手动。您将使用一个套接字套接字和它的流。

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

instead.

代替。

#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


3  

If you are looking for a fast unrolled version, this should do the trick, assuming a byte array called "b" with a length of 8:

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

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

#9


3  

I will add another answer which is the fastest one possible ׂ(yes, even more than the accepted answer), BUT it will not work for every single case. HOWEVER, it WILL work for every conceivable scenario:

我将添加另一个答案,这是最快的一种可能(是的,甚至比公认的答案还要多),但它对每一个案例都不起作用。然而,它将适用于所有可能的场景:

You can simply use String as intermediate. Note, this WILL give you the correct result even though it seems like using String might yield the wrong results AS LONG AS YOU KNOW YOU'RE WORKING WITH "NORMAL" STRINGS. This is a method to increase effectiveness and make the code simpler which in return must use some assumptions on the data strings it operates on.

您可以简单地使用字符串作为中间体。注意,这将给您正确的结果,尽管看起来使用字符串可能会产生错误的结果,只要您知道您使用的是“正常”字符串。这是一种提高效率并使代码更简单的方法,在返回时必须对其操作的数据字符串使用一些假设。

Con of using this method: If you're working with some ASCII characters like these symbols in the beginning of the ASCII table, the following lines might fail, but let's face it - you probably will never use them anyway.

使用这个方法的缺点:如果您使用的是ASCII字符,比如ASCII表开头的这些符号,下面几行可能会失败,但是让我们面对它——您可能永远不会使用它们。

Pro of using this method: Remember that most people usually work with some normal strings without any unusual characters and then the method is the simplest and fastest way to go.

使用这个方法的好处:记住,大多数人通常使用一些正常的字符串,而没有任何不寻常的字符,然后这个方法是最简单和最快的方法。

from Long to byte[]:

从长byte[]:

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

from byte[] to Long:

从byte[]长:

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

#10


1  

If you are already using an OutputStream to write to the socket, then DataOutputStream might be a good fit. Here is an example:

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

// Assumes you are currently working with a SocketOutputStream.

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

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

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

There are similar methods for short, int, float, etc. You can then use DataInputStream on the receiving side.

短、int、float等都有类似的方法,然后可以在接收方使用DataInputStream。

#1


153  

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

Or wrapped in a class to avoid repeatedly creating ByteBuffers:

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

Since this is getting so popular, I just want to mention that I think you're better off using a library like Guava in the vast majority of cases. And if you have some strange opposition to libraries, you should probably consider this answer first for native java solutions. I think the main thing my answer really has going for it is that you don't have to worry about the endian-ness of the system yourself.

既然这已经很流行了,我想说的是,我认为在绝大多数情况下使用像Guava这样的图书馆会更好。如果您对库有一些奇怪的反对意见,那么您应该首先考虑这个对原生java解决方案的回答。我认为我的答案最主要的是你不必担心系统本身的偶然性。

#2


57  

You could use the Byte conversion methods from Google Guava.

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

Example:

例子:

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

#3


49  

I tested the ByteBuffer method against plain bitwise operations but the latter is significantly faster.

我测试了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;
}

#4


12  

Why do you need the byte[]? why not just write it to the socket?

为什么需要字节[]?为什么不直接把它写在插座上呢?

I assume you mean long rather than Long, the latter needs to allow for null values.

我假设您的意思是long而不是long,后者需要允许null值。

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

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

#5


4  

You could use the implementation in org.apache.hadoop.hbase.util.Bytes http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/util/Bytes.html

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

The source code is here:

源代码在这里:

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

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 % 28长% 29

Look for the toLong and toBytes methods.

寻找toLong和toBytes方法。

I believe the software license allows you to take parts of the code and use it but please verify that.

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

#6


3  

Just write the long to a DataOutputStream with an underlying ByteArrayOutputStream. From the ByteArrayOutputStream you can get the byte-array via toByteArray():

只需将long写入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));       
        }
}

Works for other primitives accordingly.

为其他原语工作。

Hint: For TCP you do not need the byte[] manually. You will use a Socket socket and its streams

提示:对于TCP,您不需要手动。您将使用一个套接字套接字和它的流。

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

instead.

代替。

#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


3  

If you are looking for a fast unrolled version, this should do the trick, assuming a byte array called "b" with a length of 8:

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

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

#9


3  

I will add another answer which is the fastest one possible ׂ(yes, even more than the accepted answer), BUT it will not work for every single case. HOWEVER, it WILL work for every conceivable scenario:

我将添加另一个答案,这是最快的一种可能(是的,甚至比公认的答案还要多),但它对每一个案例都不起作用。然而,它将适用于所有可能的场景:

You can simply use String as intermediate. Note, this WILL give you the correct result even though it seems like using String might yield the wrong results AS LONG AS YOU KNOW YOU'RE WORKING WITH "NORMAL" STRINGS. This is a method to increase effectiveness and make the code simpler which in return must use some assumptions on the data strings it operates on.

您可以简单地使用字符串作为中间体。注意,这将给您正确的结果,尽管看起来使用字符串可能会产生错误的结果,只要您知道您使用的是“正常”字符串。这是一种提高效率并使代码更简单的方法,在返回时必须对其操作的数据字符串使用一些假设。

Con of using this method: If you're working with some ASCII characters like these symbols in the beginning of the ASCII table, the following lines might fail, but let's face it - you probably will never use them anyway.

使用这个方法的缺点:如果您使用的是ASCII字符,比如ASCII表开头的这些符号,下面几行可能会失败,但是让我们面对它——您可能永远不会使用它们。

Pro of using this method: Remember that most people usually work with some normal strings without any unusual characters and then the method is the simplest and fastest way to go.

使用这个方法的好处:记住,大多数人通常使用一些正常的字符串,而没有任何不寻常的字符,然后这个方法是最简单和最快的方法。

from Long to byte[]:

从长byte[]:

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

from byte[] to Long:

从byte[]长:

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

#10


1  

If you are already using an OutputStream to write to the socket, then DataOutputStream might be a good fit. Here is an example:

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

// Assumes you are currently working with a SocketOutputStream.

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

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

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

There are similar methods for short, int, float, etc. You can then use DataInputStream on the receiving side.

短、int、float等都有类似的方法,然后可以在接收方使用DataInputStream。