Java Byte Array - String to Byte Array


180

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

Обидва вони відрізняються від моїх надісланих даних ... Я впевнений, що мені не вистачає чогось справді простого ....

Будь-яка допомога ?!

Відповіді:


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. Чи є якийсь інший метод для цього?
Гуган

Якщо отримані вами дані є дійсно читаною людиною рядком, яку потрібно проаналізувати, як значення змінної responseу моїй відповіді, то, на жаль, ні, іншого шляху немає. Найкращим способом було б ви отримувати байти як необроблені дані (як двійкові) замість рядка, або, можливо, навіть як рядок Base64, що вимагало б лише перетворення їх назад у базове 256 (бінарне) значення.
Янік Рошон

3
Щоб додати до того, що в іншому випадку є правильною (хоча і неповною) відповіддю: 1) Будь-який байт [] масив, який перетворюється на String на Java, повинен вказати набір символів. Чи є масив байтів [] UTF-8 чи щось інше? Якщо ви не конкретні або не знаєте, що це таке, це може створювати помилки. 2) Java використовує кодування Big-Endian, але, наприклад, системи M $ використовують Little-Endian. У роботі з масивами байтів [], які є рядками (на основі символів), це не проблема. Однак, якщо масив байт [] представляє число, "цінність" джерела / цільової системи має значення.
Даррелл Тіг

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Це виводить "круту нитку" на консоль.

Це досить проклято легко.


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== 

7

Що Arrays.toString()полягає у створенні рядкового подання кожного окремого байту у вашому byteArray.

Перевірте API документації з документацією 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


2
Ні, ви не читали питання або, можливо, ви не зрозуміли проблему. Як ви зауважите, на запитання відповіли роки тому ...
0909EM

3

Вид виводу, який ви бачите зі свого байтового масиву ( [B@405217f8), також є результатом для байтового масиву нульової довжини (тобто new byte[0]). Схоже, цей рядок є посиланням на масив, а не описом вмісту масиву, як ми могли б очікувати від toString()методу звичайної колекції .

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

Якщо ви вже прочитали ці байти як String(з використанням InputStreamReader), то рядок можна перетворити в байти за допомогою getBytes()функції. Не забудьте передати потрібний набір символів як конструктору String, так і getBytes()функціям, і це буде працювати лише в тому випадку, якщо дані байта можуть бути перетворені в символи символом InputStreamReader.

Якщо ви хочете мати справу з необробленими байтами, вам слід уникати використання цього шару зчитування потоків.


2

Чи можете ви не просто надсилати байти у вигляді байтів, або перетворювати кожен байт в символ і надсилати як рядок? Якщо ви зробите це так, як є, для рядка буде потрібно як мінімум 85 символів, якщо ви надішлете лише 11 байт. Ви можете створити рядкове представлення байтів, тож це було б "[B @ 405217f8", яке можна легко перетворити на bytesабо bytearrayоб'єкт в Python. Якщо цього не зробити, ви можете представити їх як серію шістнадцяткових цифр ("5b42403430353231376638"), що містять 22 символи, які можна легко розшифрувати на стороні Python за допомогою binascii.unhexlify().


1
[B@405217f8- ідентифікатор об’єкта Java масиву, а не вміст масиву. Ідентифікатор об'єкта, безумовно, не може "легко бути перетворений в байт або об'єкт bytearray в python". Найкраще зробити розмір - це перетворити байт [] в рядок 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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.