Matriz de bytes em Java para seqüência de caracteres em matriz de bytes

180

Eu estou tentando entender um byte [] para string, representação de string da conversão de byte [] para byte [] ... Eu converto meu byte [] em uma string para enviar e espero meu serviço da Web (escrito em python) para fazer eco dos dados diretamente para o cliente.

Quando envio os dados do meu aplicativo Java ...

Arrays.toString(data.toByteArray())

Bytes para enviar ..

[B@405217f8

Enviar (este é o resultado de Arrays.toString (), que deve ser uma representação de seqüência de caracteres dos meus dados de bytes, esses dados serão enviados através do fio):

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

No lado python, o servidor python retorna uma string para o chamador (que eu vejo é o mesmo que a string que enviei para o servidor

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

O servidor deve retornar esses dados para o cliente, onde podem ser verificados.

A resposta que meu cliente recebe (como uma string) se parece com

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

Não consigo descobrir como recuperar a string recebida em um byte []

O que quer que eu pareça tentar, acabo recebendo uma matriz de bytes que se parece com a seguinte ...

[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 posso obter uma representação de bytes que é a seguinte:

B@2a80d889

Ambos são diferentes dos meus dados enviados ... Tenho certeza de que estou perdendo algo verdadeiramente simples ....

Qualquer ajuda?!

0909EM
fonte

Respostas:

272

Você não pode simplesmente pegar a string retornada e construir uma string a partir dela ... não é mais um byte[]tipo de dados, já é uma string; você precisa analisá-lo. Por exemplo :

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

** EDIT **

Você recebe uma dica do seu problema na sua pergunta, onde diz " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...", porque 91é o valor do byte [, assim [91, 45, ...como a matriz de bytes da " [-45, 1, 16, ..." string.

O método Arrays.toString()retornará uma Stringrepresentação da matriz especificada; significando que o valor retornado não será mais uma matriz. Por exemplo :

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 você pode ver, s1mantém a representação em cadeia da matriz b1 , enquanto s2mantém a representação em cadeia dos bytes contidos em b1.

Agora, no seu problema, seu servidor retorna uma string semelhante a s1, portanto, para recuperar a representação da matriz, você precisa do método construtor oposto. Se s2.getBytes()for o oposto de new String(b1), você precisará encontrar o oposto de Arrays.toString(b1), portanto, o código que colei no primeiro trecho desta resposta.

Yanick Rochon
fonte
Impressionante! Eu acho que você entendeu completamente o que eu estava procurando ... Eu não sou de Java, então não consegui descobrir a conversão de que precisava. Apenas para informações, estou enviando s1 para o servidor, e o servidor está respondendo com s1 (posso verificar se o servidor recebeu e respondeu com os dados em s1), então eu precisava do oposto de Arrays.toString () como você sugeriu ... E sua solução é muito boa! Felicidades!
0909EM
Obrigado Yanick. Mas faz loop para 2046 vezes para cada imagem como o valor de bytes.length é 2046. Existe algum outro método para fazer isso?
Gugan
Se os dados que você está recebendo são realmente uma sequência legível por humanos que precisa ser analisada como o valor da variável responsena minha resposta, então infelizmente não, não há outra maneira. A melhor maneira seria você receber os bytes como dados brutos (como binários) em vez de uma sequência, ou talvez até como uma sequência Base64, o que exigiria apenas a conversão novamente como um valor base 256 (binário).
Yanick Rochon
3
Para adicionar uma resposta correta (embora incompleta): 1) Qualquer matriz de bytes [] que está sendo convertida em uma String em Java deve especificar o conjunto de caracteres. A matriz de bytes [] é UTF-8 ou outra coisa? Não ser específico ou saber o que é isso pode criar bugs. 2) Java usa codificação Big-Endian, mas sistemas M $, por exemplo, usam Little-Endian. Ao lidar com matrizes de bytes [] que são Strings (com base em caracteres), não há problema. No entanto, se a matriz de bytes [] representar um número, a 'endianess' dos sistemas de origem / destino é importante.
Darrell Teague
130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Isso gera "string legal" para o console.

É muito fácil.

CorayThan
fonte
6
Tantas votações negativas, mas tão poucas explicações ... O que eu disse não funciona? Funcionou quando eu o usei, e a questão é como converter de bytes em strings e vice-versa, certo?
CorayThan
2
A resposta que resolveu isso é realmente marcada como a resposta. De memória, não é tão simples como você sugeriu ... Veja a resposta de Yanick, acho que você não entendeu o que estava perguntando, mas obrigado pela contribuição.
0909EM
9
@CorayThan Na verdade não, isso não resolve a questão do OP. Se você realmente ler através dele, verá que o que byte[]ele está recebendo é representado como um String; ou seja, "[97, 98, 99]"não [97, 98, 99]. Ou seja, sua resposta nem se aplica a essa situação.
precisa saber é o seguinte
2
Sua resposta é Stringa byte[]de String. Eu acho que a exigência questão é byte[]a Stringde byte[].
Wundwin Nascido
13
Pode até ser a resposta errada para a pergunta, mas me ajudou a resolver um problema. É por isso que as pessoas devem pensar um pouco mais antes de rebaixar a resposta de outra pessoa. Obrigado CorayThan!
Roberto Santos
21

O que eu fiz:

retornar aos clientes:

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

String str = Base64.encodeBase64String(result);

return str;

receber dos clientes:

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

seus dados serão transferidos neste formato:

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

O que Arrays.toString()faz é criar uma representação de string de cada byte individual no seu byteArray.

Verifique a documentação da API Arrays API

Para converter sua sequência de respostas de volta para a matriz de bytes original, você deve usar split(",")algo assim e convertê-la em uma coleção e depois converter cada item individual em um byte para recriar sua matriz de bytes.

Kal
fonte
5

É simples converter array de bytes em string e string de volta em array de bytes em java. precisamos saber quando usar 'novo' da maneira certa. Isso pode ser feito da seguinte maneira:

conversão de matriz de bytes para string:

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

Conversão de string para matriz de bytes:

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

Para obter mais detalhes, consulte: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html

user3469161
fonte
2
Não, você não leu a pergunta ou talvez não tenha entendido o problema. Como você
notará,
3

O tipo de saída que você está vendo na sua matriz de bytes ( [B@405217f8) também é uma saída para uma matriz de bytes de comprimento zero (ou seja new byte[0]). Parece que essa string é uma referência à matriz e não uma descrição do conteúdo da matriz, como seria de esperar do toString()método de uma coleção regular .

Como com outros respondentes, eu indicaria os Stringconstrutores que aceitam um byte[]parâmetro para construir uma sequência a partir do conteúdo de uma matriz de bytes. Você deve conseguir ler bytes brutos de um soquete, InputStreamse desejar obter bytes de uma conexão TCP.

Se você já leu esses bytes como String(usando um InputStreamReader), a sequência pode ser convertida em bytes usando a getBytes()função Certifique-se de passar o conjunto de caracteres desejado para o construtor String e as getBytes()funções, e isso funcionará apenas se os dados de bytes puderem ser convertidos em caracteres pelo InputStreamReader.

Se você deseja lidar com bytes não processados, evite usar essa camada de leitor de fluxo.

fuzzyBSc
fonte
2

Você não pode apenas enviar os bytes como bytes, ou converter cada byte em um caractere e enviar como uma string? Se você fizer isso, terá no mínimo 85 caracteres na sequência, quando você tiver apenas 11 bytes para enviar. Você pode criar uma representação de string dos bytes, para que seja "[B @ 405217f8", que pode ser facilmente convertido em um objeto bytesou bytearrayem Python. Caso contrário, você pode representá-los como uma série de dígitos hexadecimais ("5b42403430353231376638") ocupando 22 caracteres, que podem ser facilmente decodificados no lado do Python usando binascii.unhexlify().

JAB
fonte
1
[B@405217f8é o ID do objeto Java da matriz, não o conteúdo da matriz. O ID do objeto certamente " não pode ser facilmente convertido em um objeto de bytes ou bytes em python". O melhor que você pode fazer em termos de tamanho é converter o byte [] em uma string base64.
Boris B.
Você está correto, assumi ingenuamente que 0909EM sabia o suficiente para diferenciar entre o endereço (digitado) de um objeto e o conteúdo do objeto.
JB
2

[JDK8]

import java.util.Base64;

Para sequenciar:

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

Para bytes da matriz:

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

Se você deseja converter a string novamente em uma matriz de bytes, precisará usar String.getBytes()(ou uma função Python equivalente) e isso permitirá que você imprima a matriz de bytes original.

Martin
fonte
0

Use a API de código abaixo para converter bytecode como string em matriz de bytes.

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