Как преобразовать Long в байт [] и вернуться в java

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

Ответ 1

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

Ответ 3

Я тестировал метод 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

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

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

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

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

Ответ 5

Вы можете использовать реализацию в 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.

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

Ответ 6

Просто напишите 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));       
        }
}

Соответственно работает и для других примитивов.

Совет. Для TCP вам не требуется байт [] вручную. Вы будете использовать Socket socket и его потоки

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

вместо.

Ответ 7

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

Ответ 8

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

Вы можете просто использовать String как промежуточный. Обратите внимание, что это даст вам правильный результат, даже если кажется, что использование String может привести к неправильным результатам. КАК ДОЛГО, КАК ВЫ ЗНАЕТЕ, ВЫ РАБОТАЕТ С "НОРМАЛЬНЫМИ" СТРИНАМИ. Это метод повышения эффективности и упрощение кода, который в свою очередь должен использовать некоторые предположения для строк данных, на которых он работает.

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

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

from Long to byte []:

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

from byte [] to Long:

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

Ответ 9

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

Ответ 10

Если вы уже используете 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 и т.д. Затем вы можете использовать DataInputStream на принимающей стороны.