Вопрос-ответ

How to convert byte array to string and vice versa?

Как преобразовать массив байтов в строку и наоборот?

Мне нужно преобразовать массив байтов в строку в Android, но мой массив байтов содержит отрицательные значения.

Если я снова преобразовываю эту строку в массив байтов, значения, которые я получаю, отличаются от исходных значений массива байтов.

Что я могу сделать, чтобы получить правильное преобразование? Код, который я использую для преобразования, следующий:

// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);

// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++)
System.out.println("by1["+i+"] >> "+str1);

Я застрял в этой проблеме.

Переведено автоматически
Ответ 1

Ваш массив байтов должен иметь некоторую кодировку. Кодировка не может быть ASCII, если у вас отрицательные значения. Как только вы это выясните, вы можете преобразовать набор байтов в строку, используя:

byte[] bytes = {...}
String str = new String(bytes, StandardCharsets.UTF_8); // for UTF-8 encoding

Существует множество кодировок, которые вы можете использовать, посмотрите поддерживаемые кодировки в Oracle javadocs.

Ответ 2

"Правильное преобразование" между byte[] и String заключается в явном указании кодировки, которую вы хотите использовать. Если вы начинаете с byte[] и на самом деле он не содержит текстовых данных, нет "правильного преобразования". Strings предназначены для текста, byte[] - для двоичных данных, и единственное, что действительно разумно делать, это избегать преобразования между ними, если только это не является абсолютно необходимым.

Если вам действительно необходимо использовать String для хранения двоичных данных, то самый безопасный способ - использовать кодировку Base64.

Ответ 3

Основная проблема заключается (я думаю) в том, что вы невольно используете набор символов, для которого:

 bytes != encode(decode(bytes))

в некоторых случаях. Примером такого набора символов является UTF-8. В частности, определенные последовательности байтов не являются допустимыми кодировками в UTF-8. Если декодер UTF-8 обнаружит одну из этих последовательностей, он может отбросить байты-нарушители или декодировать их как кодовую точку Unicode для обозначения "такого символа нет". Естественно, когда вы затем попытаетесь закодировать символы в виде байтов, результат будет другим.

Решение таково:


  1. Четко указывайте кодировку символов, которую вы используете; т. е. Используйте строковый конструктор и String.toByteArray метод с явной кодировкой.

  2. Используйте правильный набор символов для ваших байтовых данных ... или альтернативно один (например, "Latin-1", где все последовательности байтов соответствуют допустимым символам Юникода.

  3. Если ваши байты (на самом деле) представляют собой двоичные данные и вы хотите иметь возможность передавать / принимать их по "текстовому" каналу, используйте что-то вроде кодировки Base64 ... который предназначен для этой цели.


Для Java наиболее распространенными наборами символов являются в java.nio.charset.StandardCharsets. Если вы кодируете строку, которая может содержать любое значение символа Юникода, то рекомендуется использовать кодировку UTF-8 (UTF_8).

Если вам нужно отображение 1: 1 в Java, то вы можете использовать латинский алфавит ISO № 1 - чаще называемый просто "Latin 1" или просто "Latin" (ISO_8859_1). Обратите внимание, что Latin-1 в Java - это версия Latin-1 для IANA, которая присваивает символы всем возможным 256 значениям, включая управляющие блоки C0 и C1. Они недоступны для печати: вы не увидите их ни в одном выводе.

Начиная с Java 8, Java содержит java.util.Base64 для кодирования / декодирования Base64. Для кодирования, безопасного для URL, вы можете захотеть использовать Base64.getUrlEncoder вместо стандартного кодировщика. Этот класс также присутствует в Android начиная с Android Oreo (8), уровень API 26.

Ответ 4

Нам просто нужно создать новый String с массивом: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java /

String s = new String(bytes);

Байты результирующей строки различаются в зависимости от того, какую кодировку вы используете. новая строка (bytes) и new String(bytes, Charset.forName("utf-8")) и новая строка(bytes, Charset.forName("utf-16")) будут иметь разные массивы байтов при вызове String#getBytes() (в зависимости от кодировки по умолчанию)

java