Tableau d'octets Java en chaîne en tableau d'octets

180

J'essaye de comprendre un octet [] en chaîne, représentation sous forme de chaîne d'octet [] en octet [] conversion ... Je convertis mon octet [] en chaîne à envoyer, j'attends alors mon service web (écrit en python) pour renvoyer les données directement au client.

Lorsque j'envoie les données depuis mon application Java ...

Arrays.toString(data.toByteArray())

Octets à envoyer.

[B@405217f8

Envoyer (Ceci est le résultat de Arrays.toString () qui devrait être une représentation sous forme de chaîne de mes données d'octet, ces données seront envoyées à travers le fil):

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

Du côté python, le serveur python renvoie une chaîne à l'appelant (que je peux voir est la même que la chaîne que j'ai envoyée au serveur

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

Le serveur doit renvoyer ces données au client, où elles peuvent être vérifiées.

La réponse que mon client reçoit (sous forme de chaîne) ressemble à

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

Je n'arrive pas à comprendre comment récupérer la chaîne reçue dans un octet []

Quoi que je semble essayer, je finis par obtenir un tableau d'octets qui ressemble à ce qui suit ...

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

ou je peux obtenir une représentation d'octet qui est la suivante:

B@2a80d889

Les deux sont différents de mes données envoyées ... Je suis sûr qu'il me manque quelque chose de vraiment simple ...

De l'aide?!

0909EM
la source

Réponses:

272

Vous ne pouvez pas simplement prendre la chaîne retournée et en construire une ... ce n'est plus un byte[]type de données, c'est déjà une chaîne; vous devez l'analyser. Par exemple :

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

** MODIFIER **

Vous obtenez un indice de votre problème dans votre question, où vous dites " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...", car il 91s'agit de la valeur d'octet pour [, de même que [91, 45, ...le tableau d'octets de la chaîne " [-45, 1, 16, ...".

La méthode Arrays.toString()retournera une Stringreprésentation du tableau spécifié; ce qui signifie que la valeur retournée ne sera plus un tableau. Par exemple :

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

Comme vous pouvez le voir, s1contient la représentation sous forme de chaîne du tableau b1 , tandis que s2contient la représentation sous forme de chaîne des octets contenus dansb1 .

Maintenant, dans votre problème, votre serveur renvoie une chaîne similaire à s1, par conséquent, pour récupérer la représentation du tableau, vous avez besoin de la méthode du constructeur opposée. Si s2.getBytes()c'est le contraire de new String(b1), vous devez trouver l'opposé de Arrays.toString(b1), donc le code que j'ai collé dans le premier extrait de cette réponse.

Yanick Rochon
la source
Impressionnant! Je pense que vous avez parfaitement compris ce que je recherchais ... Je ne suis pas d'origine Java, donc je ne pouvais pas vraiment comprendre la conversion dont j'avais besoin. Juste pour info, j'envoie s1 au serveur, et le serveur répond avec s1 (je peux vérifier que le serveur a reçu et répondu avec les données dans s1), j'ai donc besoin de l'opposé de Arrays.toString () comme vous avez suggéré ... ET votre solution est sacrément bonne! À votre santé!
0909EM
Merci Yanick. Mais il boucle 2046 fois pour chaque image car la valeur de bytes.length est 2046. Existe-t-il une autre méthode pour le faire?
Gugan
Si les données que vous recevez sont vraiment une chaîne lisible par l'homme qui doit être analysée comme la valeur de la variable responsedans ma réponse, alors malheureusement non, il n'y a pas d'autre moyen. Le meilleur moyen serait que vous receviez les octets sous forme de données brutes (sous forme binaire) au lieu d'une chaîne, ou peut-être même sous forme de chaîne Base64, ce qui ne vous obligerait qu'à la reconvertir en tant que valeur de base 256 (binaire).
Yanick Rochon le
3
Pour ajouter à ce qui est par ailleurs une réponse correcte (quoique incomplète): 1) Tout tableau d'octets [] converti en chaîne en Java doit spécifier le jeu de caractères. Le tableau byte [] est-il UTF-8 ou autre chose? Ne pas être précis ou savoir ce que c'est peut créer des bugs. 2) Java utilise l'encodage Big-Endian mais les systèmes M $ par exemple utilisent Little-Endian. Lorsqu'il s'agit de tableaux d'octets [] qui sont des chaînes (basés sur des caractères), ce n'est pas un problème. Cependant, si le tableau d'octets [] représente un nombre, la «finalité» des systèmes source / cible est importante.
Darrell Teague
130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Cela génère une "chaîne cool" vers la console.

C'est sacrément facile.

CorayThan
la source
6
Tant de votes négatifs, mais si peu d'explications ... Ce que j'ai dit ne fonctionne pas? Cela a fonctionné quand je l'ai utilisé, et la question est de savoir comment convertir des octets en chaînes et inversement, non?
CorayJour
2
La réponse qui a résolu ce problème est en fait marquée comme la réponse. De mémoire, ce n'est pas aussi simple que vous l'avez suggéré ... Voir la réponse de Yanick, je pense que vous avez mal compris ce que je demandais, mais merci pour votre contribution.
0909EM
9
@CorayThan En fait non, cela ne répond pas du tout à la question du PO. Si vous le lisez réellement, vous verrez que ce byte[]qu'il reçoit est représenté par un String; c'est à dire "[97, 98, 99]"non [97, 98, 99]. Cela signifie que votre réponse ne s'applique même pas à cette situation.
b1nary.atr0phy
2
Votre réponse est Stringà byte[]la String. Je pense que l'exigence de la question est byte[]à Stringla byte[].
Wundwin Né
13
Peut-être même la mauvaise réponse à la question posée, mais cela m'a aidé à résoudre un problème. C'est pourquoi les gens devraient réfléchir un peu plus avant de déclasser la réponse de quelqu'un d'autre. Merci CorayThan!
Roberto Santos
21

Ce que j'ai fait:

retour aux clients:

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

String str = Base64.encodeBase64String(result);

return str;

recevoir des clients:

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

vos données seront transférées dans ce format:

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

Ce qui Arrays.toString()fait est de créer une représentation sous forme de chaîne de chaque octet individuel dans votre byteArray.

Veuillez consulter la documentation de l'API Arrays API

Pour reconvertir votre chaîne de réponse dans le tableau d'octets d'origine, vous devez utiliser split(",")ou quelque chose et le convertir en une collection, puis convertir chaque élément individuel en un octet pour recréer votre tableau d'octets.

Kal
la source
5

Il est simple de convertir un tableau d'octets en chaîne et une chaîne en tableau d'octets en java. nous devons savoir quand utiliser «nouveau» de la bonne manière. Cela peut être fait comme suit:

conversion de tableau d'octets en chaîne:

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

Conversion de tableau de chaînes en octets:

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

Pour plus de détails, consultez: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

user3469161
la source
2
Non, vous n'avez pas lu la question ou peut-être n'avez-vous pas compris le problème. Comme vous le remarquerez, la question a reçu une réponse il y a des années ...
0909EM
3

Le type de sortie que vous voyez de votre tableau d'octets ( [B@405217f8) est également une sortie pour un tableau d'octets de longueur nulle (c'est-à-dire new byte[0]). Il semble que cette chaîne soit une référence au tableau plutôt qu'une description du contenu du tableau comme on pourrait s'y attendre de la toString()méthode d'une collection régulière .

Comme avec les autres répondants, je voudrais vous indiquer les Stringconstructeurs qui acceptent un byte[]paramètre pour construire une chaîne à partir du contenu d'un tableau d'octets. Vous devriez être capable de lire les octets bruts à partir d'une socketInputStream si vous souhaitez obtenir des octets à partir d'une connexion TCP.

Si vous avez déjà lu ces octets en tant que String(en utilisant un InputStreamReader), la chaîne peut être convertie en octets à l'aide de la getBytes()fonction. Assurez-vous de transmettre le jeu de caractères souhaité au constructeur et aux getBytes()fonctions String , et cela ne fonctionnera que si les données d'octet peuvent être converties en caractères par leInputStreamReader .

Si vous souhaitez traiter des octets bruts, vous devez vraiment éviter d'utiliser cette couche de lecture de flux.

fuzzyBSc
la source
2

Ne pouvez-vous pas simplement envoyer les octets sous forme d'octets, ou convertir chaque octet en caractère et l'envoyer sous forme de chaîne? Faire comme vous l'êtes prendra au moins 85 caractères dans la chaîne, alors que vous n'avez que 11 octets à envoyer. Vous pouvez créer une représentation sous forme de chaîne des octets, donc ce serait "[B @ 405217f8", qui peut facilement être converti en un objet bytesou bytearrayen Python. A défaut, vous pourriez les représenter comme une série de chiffres hexadécimaux ("5b42403430353231376638") occupant 22 caractères, qui pourraient être facilement décodés côté Python en utilisant binascii.unhexlify().

COUP
la source
1
[B@405217f8est l'ID d'objet Java du tableau, pas le contenu du tableau. L'ID d'objet ne peut certainement pas "être facilement converti en un objet bytes ou bytearray en python". Le mieux que vous puissiez faire en termes de taille est de convertir l'octet [] en une chaîne de base64.
Boris B.
Vous avez raison, j'ai naïvement supposé que 0909EM en savait assez pour différencier l'adresse (tapée) d'un objet et le contenu de l'objet.
JAB
2

[JDK8]

import java.util.Base64;

Pour enchaîner:

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

Au tableau d'octets:

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

Si vous souhaitez reconvertir la chaîne en un tableau d'octets, vous devrez utiliser String.getBytes()(ou une fonction Python équivalente) et cela vous permettra d'imprimer le tableau d'octets d'origine.

Martin
la source
0

Utilisez l'API de code ci-dessous pour convertir le bytecode sous forme de chaîne en tableau d'octets.

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