Как конвертировать Long в byte[] и обратно в java
Как преобразовать long в byte[] и обратно в Java?
Я пытаюсь преобразовать long в byte [], чтобы я мог отправить byte [] по tcp-соединению. С другой стороны, я хочу взять этот байт[] и преобразовать его обратно в двойной.
Любые советы будут оценены.
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(); } }
ответ сначала для собственных решений 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:
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[] как точный аналог выше
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
исходный код здесь:
ищите toLong и toBytes методы.
Я считаю, что лицензия на программное обеспечение позволяет вам брать части кода и использовать его, но, пожалуйста, проверьте это.
просто напишите длинный к 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; }
Я добавлю еще один ответ, который является самым быстрым из возможных ׂ(да, даже больше, чем принятый ответ), но он не будет работать для каждого отдельного случая. Тем не менее, он будет работать для каждого мыслимого сценария:
Вы можете просто использовать строку в качестве промежуточного. Обратите внимание, что это даст вам правильный результат, хотя кажется, что использование строки может привести к неправильным результатам, если вы знаете, что работаете с "нормальными" строками. Это способ увеличить эффективность и сделать код проще, который в свою очередь должен использовать некоторые предположения о строках данных, с которыми он работает.
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и т. д. Затем вы можете использовать DataInputStream на принимающей стороне.
Comments