Programming

Java에서 Long을 byte []로 변환하고 다시 변환하는 방법

procodes 2020. 6. 30. 21:09
반응형

Java에서 Long을 byte []로 변환하고 다시 변환하는 방법


Java에서 long을 byte []로 변환하고 다시 변환하는 방법은 무엇입니까? tcp 연결을 통해 byte []를 보낼 수 있도록 long을 byte []로 변환하려고합니다. 다른 쪽에서는 그 byte []를 가져 와서 다시 double로 변환하고 싶습니다. 모든 팁을 주시면 감사하겠습니다.


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

이것이 인기를 얻고 있기 때문에, 나는 대부분의 경우 구아바와 같은 라이브러리를 사용하는 것이 더 좋다고 생각합니다. 그리고 라이브러리에 대한 이상한 반대가 있다면 네이티브 Java 솔루션에 대해이 답변을 먼저 고려해야 합니다 . 내 대답은 실제로 시스템의 엔디안 자체에 대해 걱정할 필요가 없다는 것입니다.


Google Guava바이트 변환 방법사용할 수 있습니다 .

예:

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

평범한 비트 연산에 대해 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;
}

바이트 []가 왜 필요한가요? 왜 소켓에 쓰지 않습니까?

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

롤링되지 않은 빠른 버전을 찾고 있다면 길이가 8 인 "b"라는 바이트 배열을 가정하여 트릭을 수행해야합니다.

바이트 []-> 긴

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

Just write the long to a DataOutputStream with an underlying ByteArrayOutputStream. From the ByteArrayOutputStream you can get the byte-array via 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

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

instead.


You could use the implementation in org.apache.hadoop.hbase.util.Bytes 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

Look for the toLong and toBytes methods.

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


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

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.

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[] arr = String.valueOf(longVar).getBytes();

from byte[] to Long:

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

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

// 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.

참고URL : https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java

반응형