Java Byte Array to String to Byte Array

180

Я пытаюсь понять byte [] в строку, строковое представление преобразования byte [] в byte [] ... Я конвертирую свой byte [] в строку для отправки, затем я ожидаю, что мой веб-сервис (написанный на python) передать данные прямо обратно клиенту.

Когда я отправляю данные из моего Java-приложения ...

Arrays.toString(data.toByteArray())

Отправлено байтов ..

[B@405217f8

Отправить (это результат Arrays.toString (), который должен быть строковым представлением моих байтовых данных, эти данные будут отправлены по сети):

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

На стороне python, сервер python возвращает строку вызывающей стороне (что я вижу, это то же самое, что строка, которую я отправил на сервер

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

Сервер должен вернуть эти данные клиенту, где они могут быть проверены.

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

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

Я не могу понять, как вернуть полученную строку обратно в байт.

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

[91, 45, 52, 55, 44, 32, 49, 44, 32, 49, 54, 44, 32, 56, 52, 44, 32, 50, 44, 32, 49, 48, 49, 44, 32, 49, 49, 48, 44, 32, 56, 51, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 49, 48, 49, 44, 32, 51, 50, 44, 32, 55, 56, 44, 32, 55, 48, 44, 32, 54, 55, 44, 32, 51, 50, 44, 32, 54, 56, 44, 32, 57, 55, 44, 32, 49, 49, 54, 44, 32, 57, 55, 93]

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

B@2a80d889

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

Любая помощь?!

0909EM
источник

Ответы:

272

Вы не можете просто взять возвращенную строку и создать из нее строку ... это уже не byte[]тип данных, это уже строка; Вы должны разобрать это. Например :

String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]";      // response from the Python script

String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];

for (int i=0, len=bytes.length; i<len; i++) {
   bytes[i] = Byte.parseByte(byteValues[i].trim());     
}

String str = new String(bytes);

** РЕДАКТИРОВАТЬ **

Вы получите подсказку о своей проблеме в своем вопросе, где вы говорите « Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...», потому что 91это значение байта для [, а [91, 45, ...также байтовый массив строки « [-45, 1, 16, ...» строки.

Метод Arrays.toString()вернет Stringпредставление указанного массива; Это означает, что возвращаемое значение больше не будет массивом. Например :

byte[] b1 = new byte[] {97, 98, 99};

String s1 = Arrays.toString(b1);
String s2 = new String(b1);

System.out.println(s1);        // -> "[97, 98, 99]"
System.out.println(s2);        // -> "abc";

Как видите, s1содержит строковое представление массива b1 , а s2содержит строковое представление байтов, содержащихся в b1.

Теперь, в вашей задаче, ваш сервер возвращает строку, аналогичную s1, поэтому, чтобы вернуть представление массива, вам нужен противоположный метод конструктора. Если s2.getBytes()это противоположность new String(b1), вам нужно найти противоположность Arrays.toString(b1), таким образом, код, который я вставил в первый фрагмент этого ответа.

Яник Рошон
источник
Потрясающие! Я думаю, что вы полностью поняли, что я преследовал ... Я не из Java, поэтому я не мог понять, какое преобразование мне нужно. Просто для информации, я отправляю s1 на сервер, а сервер отвечает с s1 (я могу убедиться, что сервер получил и ответил с данными в s1), поэтому мне нужна была противоположность Arrays.toString () как Вы предложили ... И ваше решение чертовски хорошо! Ура!
0909EM
Спасибо, Яник. Но он зацикливается по 2046 раз для каждого изображения, так как значение bytes.length равно 2046. Есть ли другой способ сделать это?
Gugan
Если данные, которые вы получаете, на самом деле представляют собой читаемую человеком строку, которую необходимо проанализировать, например, значение переменной responseв моем ответе, то, к сожалению, нет, другого пути нет. Наилучшим способом было бы получить байты в виде необработанных данных (в виде двоичного кода) вместо строки или, возможно, даже в виде строки Base64, что потребовало бы только преобразования ее обратно в базовое 256 (двоичное) значение.
Яник Рошон
3
Чтобы добавить к тому, что в противном случае является правильным (хотя и неполным) ответом: 1) Любой массив байтов [], преобразуемый в строку в Java, должен указывать набор символов. Является ли массив байтов [] UTF-8 или что-то еще? Не быть конкретным или не зная, что это может создать ошибки. 2) Java использует кодирование Big-Endian, но, например, системы M $ используют Little-Endian. При работе с массивами byte [], которые являются строками (символьными), это не проблема. Однако, если массив byte [] представляет число, значение 'endianess' системы источника / цели имеет значение.
Даррелл Тиг
130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Это выводит «классную строку» на консоль.

Это чертовски легко.

CorayThan
источник
6
Так много отрицательных, но так мало объяснений ... Неужели то, что я сказал, не работает? Это сработало, когда я его использовал, и вопрос в том, как преобразовать байты в строки и обратно, верно?
CorayThan
2
Ответ, который решил это, фактически отмечен как ответ. По памяти это не так просто, как вы предлагали ... Посмотрите ответ Яника, я думаю, вы неправильно поняли то, что я просил, но спасибо за вклад.
0909EM
9
@CorayThan На самом деле нет, это вообще не касается вопроса ОП. Если вы на самом деле прочитаете его, вы увидите, что byte[]он получает представлен как String; то есть "[97, 98, 99]"нет [97, 98, 99]. Это означает, что ваш ответ даже не относится к этой ситуации.
b1nary.atr0phy
2
Ваш ответ Stringна byte[]в String. Я думаю, что вопрос byte[]в том, Stringчтобы byte[].
Вандвин родился
13
Может даже быть неправильный ответ на заданный вопрос, но это помогло мне решить проблему. Вот почему люди должны немного подумать, прежде чем понизить чей-то ответ. Спасибо CorayThan!
Роберто Сантос
21

Что я сделал:

вернуться к клиентам:

byte[] result = ****encrypted data****;

String str = Base64.encodeBase64String(result);

return str;

получать от клиентов:

 byte[] bytes = Base64.decodeBase64(str);

Ваши данные будут переданы в следующем формате:

OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA== 
Saorikido
источник
7

Что Arrays.toString()делает, это создает строковое представление каждого отдельного байта в вашем byteArray.

Пожалуйста, проверьте API документацию Arrays API

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

Кал
источник
5

Его просто конвертировать байтовый массив в строку и строку обратно в байтовый массив в Java. нам нужно знать, когда правильно использовать «новый». Это можно сделать следующим образом:

преобразование байтового массива в строку:

byte[] bytes = initializeByteArray();
String str = new String(bytes);

Преобразование строки в байтовый массив:

String str = "Hello"
byte[] bytes = str.getBytes();

Для получения более подробной информации, смотрите: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

user3469161
источник
2
Нет, вы не читали вопрос или, возможно, вы не поняли проблему. Как вы заметите, на вопрос был дан ответ несколько лет назад ...
0909EM
3

Тип вывода, который вы видите из вашего байтового массива ( [B@405217f8), также является выходом для байтового массива нулевой длины (т.е. new byte[0]). Похоже, что эта строка является ссылкой на массив, а не описанием содержимого массива, как мы могли бы ожидать от toString()метода обычной коллекции .

Как и в случае с другими респондентами, я бы указал на Stringконструкторы, которые принимают byte[]параметр для построения строки из содержимого байтового массива. Вы должны иметь возможность читать необработанные байты из сокетов, InputStreamесли вы хотите получать байты из TCP-соединения.

Если вы уже прочитали эти байты как String(используя InputStreamReader), то строку можно преобразовать в байты с помощью getBytes()функции. Обязательно передайте желаемый набор символов как конструктору String, так и getBytes()функциям, и это будет работать только в том случае, если байтовые данные могут быть преобразованы в символы с помощью InputStreamReader.

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

fuzzyBSc
источник
2

Можете ли вы не просто отправить байты как байты, или преобразовать каждый байт в символ и отправить как строку? Выполнение, как вы, займет не менее 85 символов в строке, когда у вас есть только 11 байтов для отправки. Вы можете создать строковое представление байтов, поэтому это будет «[B @ 405217f8», который можно легко преобразовать в объект bytesили bytearrayобъект в Python. В противном случае вы можете представить их как последовательность шестнадцатеричных цифр («5b42403430353231376638»), занимающую 22 символа, которые можно легко декодировать на стороне Python с помощью binascii.unhexlify().

JAB
источник
1
[B@405217f8это идентификатор объекта Java массива, а не его содержимое. Идентификатор объекта, конечно, не может «легко быть преобразован в байты или объекты байтовых массивов в python». Лучшее, что вы можете сделать по размеру, это преобразовать byte [] в строку base64.
Борис Б.
Вы правы, я наивно полагал, что 0909EM знал достаточно, чтобы различать (напечатанный) адрес объекта и его содержимое.
JAB
2

[JDK8]

import java.util.Base64;

Нанизывать:

String str = Base64.getEncoder().encode(new byte[]{ -47, 1, 16, ... });

К байтовому массиву:

byte[] bytes = Base64.getDecoder().decode("JVBERi0xLjQKMyAwIG9iago8P...");
Патрисио Кордова
источник
1

Если вы хотите преобразовать строку обратно в байтовый массив, вам нужно будет использовать String.getBytes()(или эквивалентную функцию Python), и это позволит вам распечатать исходный байтовый массив.

Мартин
источник
0

Используйте приведенный ниже API-интерфейс для преобразования байтового кода в виде строки в байтовый массив.

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
Аджай Кумар
источник
-1

[JAVA 8]

import java.util.Base64;

String dummy= "dummy string";
byte[] byteArray = dummy.getBytes();

byte[] salt = new byte[]{ -47, 1, 16, ... }
String encoded = Base64.getEncoder().encodeToString(salt);
3logy
источник