Как преобразовать Long в byte[] и обратно в java

Как преобразовать long в byte[] и обратно в Java? Я пытаюсь преобразовать long в byte [], чтобы я мог отправить байт[] через tcp-соединение. С другой стороны, я хочу взять этот байт[] и преобразовать его обратно в double. Любые советы будут оценены.

10 ответов


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 в подавляющем большинстве случаев. И если у вас есть какая-то странная оппозиция библиотекам, вам, вероятно, следует рассмотреть ответ сначала для собственных решений 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;
}

зачем вам нужен байт[]? почему бы просто не записать его в сокет?

Я полагаю, вы имеете в виду долго, а не долго, последний должен учитывать значения null.

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

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

Если вы ищете быструю развернутую версию, это должно сделать трюк, предполагая, что массив байтов называется " 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);

долго -> байт[] как точный аналог выше

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

вы можете использовать реализацию в org.апаш.платформа Hadoop.в HBase.утиль.Байты 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

ищите толонг и тобайт методы.

Я считаю, что лицензия на программное обеспечение позволяет вам брать части кода и использовать его, но, пожалуйста, проверьте это.


просто напишите длинный в 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 и его потоки

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

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

Я добавлю еще один ответ, который является самым быстрым из возможных ׂ(да, даже больше, чем принятый ответ), но он не будет работать для каждого отдельного случая. Тем не менее, он будет работать для каждого мыслимого сценария:

Вы можете просто использовать строку в качестве промежуточного звена. Обратите внимание, что это даст вам правильный результат, даже если кажется, что использование String может дать неправильные результаты, если вы знаете, что работаете с "нормальными" строками. Это способ увеличить эффективность и сделать код проще, который взамен должен использовать некоторые предположения о строках данных, с которыми он работает.

Con использования этого метода: если вы работаете с некоторыми символами ASCII, как эти символы в начале таблицы ASCII, следующие строки могут потерпеть неудачу, но давайте посмотрим правде в глаза - вы, вероятно, никогда не будете использовать их в любом случае.

Pro использования этого метода: помните, что большинство людей обычно работают с некоторыми нормальными строками без каких-либо необычных символов и тогда метод является самым простым и быстрым способом.

от Long до byte []:

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

от byte[] до Long:

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

если вы уже используете OutputStream для записи в сокет, затем DataOutputStream может быть, подойдет. Вот пример:

// Assumes you are currently working with a SocketOutputStream.

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

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

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

существуют аналогичные методы для short, int, float, etc. Затем вы можете использовать DataInputStream на принимающей стороне.