Java Byte Array a Cadena a Byte Array

180

Estoy tratando de entender un byte [] a cadena, representación de cadena de conversión de byte [] a byte [] ... Convierto mi byte [] a una cadena para enviar, luego espero mi servicio web (escrito en python) para hacer eco de los datos directamente al cliente.

Cuando envío los datos desde mi aplicación Java ...

Arrays.toString(data.toByteArray())

Bytes para enviar ..

[B@405217f8

Enviar (Este es el resultado de Arrays.toString () que debería ser una representación de cadena de mis datos de bytes, estos datos se enviarán a través del cable):

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

En el lado de Python, el servidor Python devuelve una cadena a la persona que llama (que puedo ver es la misma que la cadena que envié al servidor

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

El servidor debe devolver estos datos al cliente, donde se pueden verificar.

La respuesta que recibe mi cliente (como una cadena) se ve como

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

Parece que no puedo entender cómo recuperar la cadena recibida en un byte []

Lo que sea que intente, termino obteniendo una matriz de bytes que se ve de la siguiente manera ...

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

o puedo obtener una representación de bytes que es la siguiente:

B@2a80d889

Ambos son diferentes de mis datos enviados ... Estoy seguro de que me falta algo realmente simple ...

¡¿Alguna ayuda?!

0909EM
fuente

Respuestas:

272

No puede simplemente tomar la cadena devuelta y construir una cadena a partir de ella ... ya no es un byte[]tipo de datos, ya es una cadena; necesitas analizarlo. Por ejemplo :

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

** EDITAR **

Obtiene una pista de su problema en su pregunta, donde dice " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...", porque 91es el valor de byte para [, también lo [91, 45, ...es la matriz de bytes de la cadena " [-45, 1, 16, ...".

El método Arrays.toString()devolverá una Stringrepresentación de la matriz especificada; lo que significa que el valor devuelto ya no será una matriz. Por ejemplo :

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

Como puede ver, s1contiene la representación de cadena de la matriz b1 , mientras que s2contiene la representación de cadena de los bytes contenidos en b1.

Ahora, en su problema, su servidor devuelve una cadena similar a s1, por lo tanto, para recuperar la representación de la matriz, necesita el método del constructor opuesto. Si s2.getBytes()es lo contrario de new String(b1), debe encontrar lo contrario de Arrays.toString(b1), por lo tanto, el código que pegué en el primer fragmento de esta respuesta.

Yanick Rochon
fuente
¡Increíble! Creo que has entendido completamente lo que buscaba ... No soy de un entorno Java, por lo que realmente no pude entender la conversión que necesitaba. Solo para información, estoy enviando s1 al servidor, y el servidor responde con s1 (puedo verificar que el servidor recibió y respondió con los datos en s1), por lo que necesitaba lo contrario de Arrays.toString () como sugirió ... ¡Y su solución es bastante buena! ¡Salud!
0909EM
Gracias Yanick Pero se repite 2046 veces para cada imagen, ya que el valor de bytes.length es 2046. ¿Hay algún otro método para hacer esto?
Gugan
Si los datos que está recibiendo son realmente una cadena legible por humanos que necesita analizarse como el valor de la variable responseen mi respuesta, entonces desafortunadamente no, no hay otra manera. La mejor manera sería que recibas los bytes como datos sin procesar (como binarios) en lugar de una cadena, o tal vez incluso como una cadena Base64, lo que solo requeriría que lo vuelvas a convertir como un valor base 256 (binario).
Yanick Rochon
3
Para agregar a lo que de otro modo es una respuesta correcta (aunque incompleta): 1) Cualquier conjunto de bytes [] que se convierta en una Cadena en Java debe especificar el conjunto de caracteres. ¿El byte [] es UTF-8 o algo más? No ser específico o saber de qué se trata puede crear errores. 2) Java usa codificación Big-Endian pero los sistemas M $, por ejemplo, usan Little-Endian. Cuando se trata de matrices de bytes [] que son cadenas (basadas en caracteres), no hay problema. Sin embargo, si el conjunto de bytes [] representa un número, la 'resistencia' de los sistemas de origen / destino es importante.
Darrell Teague
130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Eso genera "cadena genial" a la consola.

Es bastante fácil.

CorayThan
fuente
66
Tantos votos negativos, pero tan pocas explicaciones ... ¿Lo que dije no funciona? Funcionó cuando lo usé, y la pregunta es cómo convertir de bytes a cadenas y viceversa, ¿verdad?
CorayThan
2
La respuesta que resolvió esto en realidad está marcada como la respuesta. De memoria, no es tan simple como has sugerido ... Mira la respuesta de Yanick, creo que has entendido mal lo que estaba preguntando, pero gracias por el aporte.
0909EM
9
@CorayThan En realidad no, esto no responde a la pregunta del OP en absoluto. Si realmente lo lees, verás que el byte[]que está recibiendo se representa como a String; es decir, "[97, 98, 99]"no [97, 98, 99]. Es decir, su respuesta ni siquiera se aplica a esta situación.
b1nary.atr0phy
2
Su respuesta es Stringque byte[]a String. Creo que la pregunta es requisito byte[]para Stringa byte[].
Wundwin nació
13
Incluso puede ser la respuesta incorrecta para la pregunta formulada, pero me ayudó a resolver un problema. Es por eso que la gente debería pensar un poco más antes de degradar la respuesta de otra persona. Gracias CorayThan!
Roberto Santos
21

Lo que hice:

volver a los clientes:

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

String str = Base64.encodeBase64String(result);

return str;

recibir de los clientes:

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

sus datos serán transferidos en este formato:

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

Lo que Arrays.toString()hace es crear una representación de cadena de cada byte individual en su byteArray.

Por favor, consulte la documentación de la API Arrays API

Para convertir su cadena de respuesta de nuevo a la matriz de bytes original, debe usar split(",")o algo así y convertirla en una colección y luego convertir cada elemento individual allí en un byte para recrear su matriz de bytes.

Kal
fuente
5

Es simple convertir la matriz de bytes en una cadena y volver a la cadena de bytes en Java. Necesitamos saber cuándo usar 'nuevo' de la manera correcta. Se puede hacer de la siguiente manera:

conversión de matriz de bytes a cadena:

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

Cadena de conversión de matriz de bytes:

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

Para obtener más detalles, consulte: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

usuario3469161
fuente
2
No, no has leído la pregunta o quizás no has entendido el problema. Como
notarás,
3

El tipo de salida que está viendo desde su matriz de bytes ( [B@405217f8) también es una salida para una matriz de bytes de longitud cero (es decir new byte[0]). Parece que esta cadena es una referencia a la matriz en lugar de una descripción de los contenidos de la matriz como podríamos esperar de un toString()método de colección regular .

Al igual que con otros encuestados, le diría a los Stringconstructores que aceptan un byte[]parámetro para construir una cadena a partir del contenido de una matriz de bytes. Debería poder leer bytes sin procesar de un socket InputStreamsi desea obtener bytes de una conexión TCP.

Si ya ha leído esos bytes como a String(usando un InputStreamReader), entonces, la cadena se puede convertir a bytes usando la getBytes()función. Asegúrese de pasar el conjunto de caracteres deseado tanto al constructor de cadena como a las getBytes()funciones, y esto solo funcionará si los datos de bytes pueden convertirse en caracteres mediante el InputStreamReader.

Si desea lidiar con bytes sin procesar, realmente debe evitar usar esta capa de lector de flujo.

fuzzyBSc
fuente
2

¿No puede simplemente enviar los bytes como bytes o convertir cada byte en un carácter y enviarlo como una cadena? Hacerlo como está ocupará un mínimo de 85 caracteres en la cadena, cuando solo tiene 11 bytes para enviar. Se puede crear una representación de cadena de los bytes, por lo que sería "[B @ 405217f8", que puede ser fácilmente convertida en una byteso bytearrayobjeto en Python. De lo contrario, podría representarlos como una serie de dígitos hexadecimales ("5b42403430353231376638") que ocupan 22 caracteres, que podrían decodificarse fácilmente en el lado de Python binascii.unhexlify().

PINCHAZO
fuente
1
[B@405217f8es el ID de objeto Java de la matriz, no el contenido de la matriz. La identificación del objeto ciertamente no puede "convertirse fácilmente en un objeto bytes o bytearray en python". Lo mejor que puede hacer en cuanto al tamaño es convertir el byte [] en una cadena base64.
Boris B.
Tienes razón, ingenuamente asumí que 0909EM sabía lo suficiente como para diferenciar entre la dirección (escrita) de un objeto y el contenido del objeto.
JAB
2

[JDK8]

import java.util.Base64;

Encadenar:

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

Para la matriz de bytes:

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

Si desea convertir la cadena de nuevo en una matriz de bytes, deberá usarla String.getBytes()(o una función equivalente de Python) y esto le permitirá imprimir la matriz de bytes original.

Martín
fuente
0

Use la siguiente API de código para convertir bytecode como cadena a Byte array.

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
Ajay Kumar
fuente
-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);
3logía
fuente