Java Byte Array zu String zu Byte Array

180

Ich versuche, ein Byte [] in einen String zu verstehen, eine String-Darstellung der Konvertierung von Byte [] in Byte [] ... Ich konvertiere mein Byte [] in einen zu sendenden String und erwarte dann meinen Webdienst (in Python geschrieben). um die Daten direkt an den Client zurückzugeben.

Wenn ich die Daten von meiner Java-Anwendung sende ...

Arrays.toString(data.toByteArray())

Zu sendende Bytes ..

[B@405217f8

Senden (Dies ist das Ergebnis von Arrays.toString (), das eine Zeichenfolgendarstellung meiner Byte-Daten sein sollte. Diese Daten werden über die Leitung gesendet.):

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

Auf der Python-Seite gibt der Python-Server eine Zeichenfolge an den Aufrufer zurück (die meiner Ansicht nach mit der Zeichenfolge übereinstimmt, die ich an den Server gesendet habe

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

Der Server sollte diese Daten an den Client zurückgeben, wo sie überprüft werden können.

Die Antwort, die mein Client erhält (als Zeichenfolge), sieht aus

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

Ich kann anscheinend nicht herausfinden, wie ich die empfangene Zeichenfolge wieder in ein Byte umwandeln kann []

Was auch immer ich zu versuchen scheine, am Ende bekomme ich ein Byte-Array, das wie folgt aussieht ...

[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]

oder ich kann eine Bytedarstellung erhalten, die wie folgt lautet:

B@2a80d889

Beide unterscheiden sich von meinen gesendeten Daten ... Ich bin sicher, ich vermisse etwas wirklich Einfaches ...

Irgendeine Hilfe?!

0909EM
quelle

Antworten:

272

Sie können nicht einfach die zurückgegebene Zeichenfolge nehmen und daraus eine Zeichenfolge byte[]erstellen. Es handelt sich nicht mehr um einen Datentyp, sondern bereits um eine Zeichenfolge. Sie müssen es analysieren. Zum Beispiel :

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

** BEARBEITEN **

Sie erhalten einen Hinweis auf Ihr Problem in Ihrer Frage, in der Sie " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ..." sagen , weil 91der Byte-Wert für ist [, ebenso [91, 45, ...wie das Byte-Array der Zeichenfolge " [-45, 1, 16, ...".

Die Methode Arrays.toString()gibt eine StringDarstellung des angegebenen Arrays zurück. Dies bedeutet, dass der zurückgegebene Wert kein Array mehr ist. Zum Beispiel :

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

Wie Sie sehen können, s1enthält die Zeichenfolgendarstellung des Arrays b1 , während s2die Zeichenfolgendarstellung der darin enthaltenen Bytes enthalten ist b1.

In Ihrem Problem gibt Ihr Server eine ähnliche Zeichenfolge zurück. s1Um die Array-Darstellung wiederherzustellen, benötigen Sie die entgegengesetzte Konstruktormethode. Wenn s2.getBytes()das Gegenteil von ist new String(b1), müssen Sie das Gegenteil von finden Arrays.toString(b1), also den Code, den ich im ersten Ausschnitt dieser Antwort eingefügt habe.

Yanick Rochon
quelle
Genial! Ich denke, Sie haben vollständig verstanden, wonach ich gesucht habe ... Ich habe keinen Java-Hintergrund, daher konnte ich die benötigte Konvertierung nicht wirklich herausfinden. Nur zur Information, ich sende s1 an den Server und der Server antwortet mit s1 (ich kann überprüfen, ob der Server die Daten in s1 empfangen und mit diesen geantwortet hat), also brauchte ich das Gegenteil von Arrays.toString () as Sie haben vorgeschlagen ... UND Ihre Lösung ist verdammt gut! Prost!
0909EM
Danke Yanick. Es wird jedoch für jedes Bild 2046 Mal wiederholt, da der Wert von bytes.length 2046 beträgt. Gibt es eine andere Methode, um dies zu tun?
Gugan
Wenn die Daten, die Sie empfangen, wirklich eine von Menschen lesbare Zeichenfolge sind, die wie der Wert der Variablen responsein meiner Antwort analysiert werden muss , gibt es leider keinen anderen Weg. Am besten empfangen Sie die Bytes als Rohdaten (als Binärdaten) anstelle einer Zeichenfolge oder sogar als Base64-Zeichenfolge, sodass Sie sie nur als Basis-256-Wert (Binärwert) zurückkonvertieren müssen.
Yanick Rochon
3
So fügen Sie eine ansonsten korrekte (wenn auch unvollständige) Antwort hinzu: 1) Jedes Byte [] -Array, das in Java in einen String konvertiert wird, sollte den Zeichensatz angeben. Ist das Byte [] Array UTF-8 oder etwas anderes? Nicht spezifisch zu sein oder zu wissen, was es ist, kann Fehler verursachen. 2) Java verwendet die Big-Endian-Codierung, aber M $ -Systeme verwenden beispielsweise Little-Endian. Beim Umgang mit Byte [] -Arrays, die Strings sind (zeichenbasiert), ist dies kein Problem. Wenn das Byte [] -Array jedoch eine Zahl darstellt, ist die 'Endianess' des Quell- / Zielsystems von Bedeutung.
Darrell Teague
130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Das gibt "cool string" an die Konsole aus.

Es ist verdammt einfach.

CorayThan
quelle
6
So viele Abstimmungen, aber so wenige Erklärungen ... Funktioniert das, was ich gesagt habe, nicht? Es hat funktioniert, als ich es verwendet habe, und die Frage ist, wie man von Bytes in Strings und wieder zurück konvertiert, oder?
CorayThan
2
Die Antwort, die dies gelöst hat, wird tatsächlich als Antwort markiert. Aus dem Gedächtnis ist es nicht so einfach, wie Sie vorgeschlagen haben ... Siehe Yanicks Antwort, ich glaube, Sie haben falsch verstanden, was ich gefragt habe, aber danke für die Eingabe.
0909EM
9
@CorayThan Eigentlich nein, dies geht überhaupt nicht auf die Frage des OP ein. Wenn Sie es tatsächlich durchlesen, werden Sie sehen, dass das, was byte[]er empfängt, als dargestellt wird String; dh "[97, 98, 99]"nicht [97, 98, 99]. Das heißt, Ihre Antwort trifft nicht einmal auf diese Situation zu.
b1nary.atr0phy
2
Ihre Antwort ist Stringbis byte[]auf String. Ich denke , die Frage Forderung ist byte[]zu Stringzu byte[].
Wundwin Geboren
13
Vielleicht ist es sogar die falsche Antwort auf die gestellte Frage, aber es hat mir geholfen, ein Problem zu lösen. Deshalb sollten die Leute etwas mehr nachdenken, bevor sie die Antwort eines anderen herabstufen. Vielen Dank, dass Sie CorayThan!
Roberto Santos
21

Was ich getan habe:

Rückkehr zu den Kunden:

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

String str = Base64.encodeBase64String(result);

return str;

von Kunden erhalten:

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

Ihre Daten werden in diesem Format übertragen:

OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA== 
Saorikido
quelle
7

Sie Arrays.toString()erstellen eine Zeichenfolgendarstellung für jedes einzelne Byte in Ihrem byteArray.

Bitte überprüfen Sie die API-Dokumentation Arrays API

Um Ihre Antwortzeichenfolge wieder in das ursprüngliche Byte-Array zu konvertieren, müssen Sie split(",")oder etwas verwenden und es in eine Sammlung konvertieren und dann jedes einzelne Element dort in ein Byte konvertieren, um Ihr Byte-Array neu zu erstellen.

Kal
quelle
5

Es ist einfach, Byte-Array in String und String zurück in Byte-Array in Java zu konvertieren. Wir müssen wissen, wann wir 'new' richtig einsetzen müssen. Dies kann wie folgt erfolgen:

Umwandlung von Byte-Array in String:

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

Konvertierung von Zeichenfolgen in Byte-Arrays:

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

Weitere Informationen finden Sie unter: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

user3469161
quelle
2
Nein, Sie haben die Frage nicht gelesen oder das Problem möglicherweise nicht verstanden. Wie Sie feststellen werden, wurde die Frage vor Jahren beantwortet ...
0909EM
3

Die Art der Ausgabe, die Sie von Ihrem Byte-Array ( [B@405217f8) sehen, ist auch eine Ausgabe für ein Byte-Array mit der Länge Null (dh new byte[0]). Es sieht so aus, als ob diese Zeichenfolge eher eine Referenz auf das Array als eine Beschreibung des Inhalts des Arrays ist, wie wir es von der toString()Methode einer regulären Sammlung erwarten können .

Wie bei anderen Befragten würde ich Sie auf die StringKonstruktoren verweisen , die einen byte[]Parameter akzeptieren , um eine Zeichenfolge aus dem Inhalt eines Byte-Arrays zu erstellen. Sie sollten in der Lage sein, Rohbytes von einem Socket zu lesen, InputStreamwenn Sie Bytes von einer TCP-Verbindung erhalten möchten.

Wenn Sie diese Bytes bereits als String(mit einem InputStreamReader) gelesen haben , kann die Zeichenfolge mit der getBytes()Funktion in Bytes konvertiert werden . Stellen Sie sicher, dass Sie den gewünschten Zeichensatz sowohl an den String-Konstruktor als auch an die getBytes()Funktionen übergeben. Dies funktioniert nur, wenn die Byte-Daten von der in Zeichen umgewandelt werden können InputStreamReader.

Wenn Sie mit Rohbytes umgehen möchten, sollten Sie die Verwendung dieser Stream-Reader-Schicht wirklich vermeiden.

fuzzyBSc
quelle
2

Können Sie die Bytes nicht einfach als Bytes senden oder jedes Byte in ein Zeichen konvertieren und als Zeichenfolge senden? Wenn Sie es so machen, wie Sie es sind, werden mindestens 85 Zeichen in der Zeichenfolge benötigt, wenn Sie nur 11 Bytes senden müssen. Sie können eine Zeichenfolgendarstellung der Bytes erstellen, also "[B @ 405217f8", die in Python problemlos in ein bytesoder bytearray-Objekt konvertiert werden kann . Andernfalls können Sie sie als eine Reihe von hexadezimalen Ziffern ("5b42403430353231376638") darstellen, die 22 Zeichen enthalten und auf der Python-Seite mit einfach dekodiert werden können binascii.unhexlify().

JAB
quelle
1
[B@405217f8ist die Java-Objekt-ID des Arrays, nicht der Inhalt des Arrays. Die Objekt-ID kann sicherlich nicht "einfach in ein Byte- oder Bytearray-Objekt in Python konvertiert werden". Das Beste, was Sie in Bezug auf die Größe tun können, ist, das Byte [] in eine Base64-Zeichenfolge zu konvertieren.
Boris B.
Sie haben Recht, ich habe naiv angenommen, dass 0909EM genug wusste, um zwischen der (getippten) Adresse eines Objekts und dem Inhalt des Objekts zu unterscheiden.
JAB
2

[JDK8]

import java.util.Base64;

Zum String:

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

Byte-Array:

byte[] bytes = Base64.getDecoder().decode("JVBERi0xLjQKMyAwIG9iago8P...");
Patricio Córdova
quelle
1

Wenn Sie die Zeichenfolge wieder in ein Byte-Array konvertieren möchten, müssen Sie String.getBytes()(oder eine entsprechende Python-Funktion) verwenden. Auf diese Weise können Sie das ursprüngliche Byte-Array ausdrucken.

Martin
quelle
0

Verwenden Sie die folgende Code-API, um Bytecode als Zeichenfolge in Byte-Array zu konvertieren.

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
Ajay Kumar
quelle
-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
quelle