Jak przekonwertować Long na bajt [] i z powrotem w Javie

Jak przekonwertować długi na bajt [] i z powrotem w Javie? Próbuję przekonwertować długi na bajt [], aby móc wysłać bajt [] przez połączenie tcp. Z drugiej strony chcę wziąć ten bajt[] i zamienić go z powrotem na podwójny. Wszelkie wskazówki będą mile widziane.

Author: Emre801, 2010-12-20

10 answers

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

Lub zawinięte w klasę, aby uniknąć wielokrotnego tworzenia buforów bajtowych:

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

Ponieważ to staje się tak popularne, chcę tylko wspomnieć, że myślę, że lepiej korzystać z biblioteki jak Guava w zdecydowanej większości przypadków. A jeśli masz jakiś dziwny sprzeciw wobec bibliotek, prawdopodobnie powinieneś rozważyć tę odpowiedź najpierw dla natywnych rozwiązań java. Myślę, że najważniejsza jest moja odpowiedź na to, że nie musisz się martwić o endian-ness samego systemu.

 163
Author: Brad Mace,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59

Możesz użyć metod konwersji bajtów z Google Guava .

Przykład:

byte[] bytes = Longs.toByteArray(12345L);
 60
Author: Sonson123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 10:51:15

Przetestowałem metodę ByteBuffer pod kątem zwykłych operacji bitowych, ale ta ostatnia jest znacznie szybsza.

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;
}
 56
Author: Wytze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-18 20:34:22

Po co Ci bajt []? dlaczego po prostu nie napiszesz tego do gniazdka?

Zakładam, że masz na myśli long zamiast Long , ten ostatni musi pozwolić na wartości null.

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

DataInputStream dis = new DataInputStream(
     new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();
 13
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-24 08:43:52

Jeśli szukasz szybko rozwijanej wersji, powinno to załatwić sprawę, zakładając tablicę bajtów o nazwie "b" o długości 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);

Long - > byte [] jako dokładny odpowiednik powyższego

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)};
 6
Author: Michael Böckling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 14:19:18

Możesz użyć implementacji w org.Apacz.hadoop.hbase.util.Bajty http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/util/Bytes.html

Kod źródłowy jest tutaj:

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

Poszukaj metod tolonga i tobytesa.

I believe the software license pozwala na pobranie części kodu i użycie go, ale proszę to sprawdzić.

 4
Author: Marquez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-12 17:25:58

Wystarczy zapisać long doDataOutputStream z bazowymByteArrayOutputStream . Z ByteArrayOutputStream można uzyskać tablicę bajtów poprzez 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));       
        }
}

Działa odpowiednio dla innych prymitywów.

Wskazówka: dla TCP nie potrzebujesz bajtu[] ręcznie. Użyjesz gniazda socket i jego strumienie

OutputStream os=socket.getOutputStream(); 
DataOutputStream dos=new DataOutputStream(os);
dos.writeLong(l);
//etc ..
Zamiast tego.
 3
Author: Michael Konietzka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-19 22:32:27
 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;
    }
 3
Author: maziar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-12 16:05:12

Dodam jeszcze jedną odpowiedź, która jest najszybsza z możliwych ׂ(tak, nawet więcej niż zaakceptowana odpowiedź), ale nie będzie działać w każdym przypadku. Jednak będzie działać dla każdego możliwego scenariusza:

Możesz po prostu użyć łańcucha jako pośredniego. Uwaga, To da ci poprawny wynik, nawet jeśli wydaje się, że używanie ciągów może przynieść złe wyniki, o ile wiesz, że pracujesz z "normalnymi" ciągami. Jest to metoda na zwiększenie efektywności i uczynienie kodu prostsze, które w zamian muszą stosować pewne założenia dotyczące ciągów danych, na których działa.

Con używania tej metody: Jeśli pracujesz z niektórymi znakami ASCII, takimi jak te symbole na początku tabeli ASCII, następujące linie mogą się nie udać, ale spójrzmy prawdzie w oczy - prawdopodobnie nigdy ich nie użyjesz.

Pro korzystania z tej metody: pamiętaj, że większość ludzi zwykle pracuje z normalnymi ciągami bez żadnych nietypowych znaków i wtedy metoda jest najprostszy i najszybszy sposób.

Od Długiego do bajtu []:

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

Od bajtu [] do Long:

long longVar = Long.valueOf(new String(byteArr)).longValue();
 3
Author: Yonatan Nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-14 10:20:23

Jeśli używasz już OutputStream do zapisu do gniazda, to DataOutputStream może być dobrym rozwiązaniem. Oto przykład:

// Assumes you are currently working with a SocketOutputStream.

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

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

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

Istnieją podobne metody dla short, int, float, itd. Następnie możesz użyć DataInputStream po stronie odbiorczej.

 1
Author: Matt Solnit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-19 21:29:25