Eu tenho que converter uma matriz de bytes em string no Android, mas minha matriz de bytes contém valores negativos.
Se eu converter essa sequência novamente em matriz de bytes, os valores que estou recebendo são diferentes dos valores originais da matriz de bytes.
O que posso fazer para obter uma conversão adequada? O código que estou usando para fazer a conversão é o seguinte:
// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);
// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++)
System.out.println("by1["+i+"] >> "+str1);
Estou preso neste problema.
byte[]
para seus dados binários eString
seu texto?Respostas:
Sua matriz de bytes deve ter alguma codificação. A codificação não pode ser ASCII se você tiver valores negativos. Depois de descobrir isso, você pode converter um conjunto de bytes em uma String usando:
Há um monte de codificações que você pode usar, olhada na classe Charset nos javadocs Sun .
fonte
UTF-8
?String str = new String(bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
A "conversão adequada" entre
byte[]
eString
deve declarar explicitamente a codificação que você deseja usar. Se você começar com umbyte[]
e ele não contiver dados de texto, não haverá "conversão adequada".String
s são para texto,byte[]
são para dados binários, e a única coisa realmente sensata a fazer é evitar conversão entre eles, a menos que seja absolutamente necessário.Se você realmente precisa usar a
String
para armazenar dados binários, a maneira mais segura é usar a codificação Base64 .fonte
O principal problema é que você involuntariamente está usando um conjunto de caracteres para o qual:
em alguns casos. UTF-8 é um exemplo desse conjunto de caracteres. Especificamente, certas seqüências de bytes não são codificações válidas em UTF-8. Se o decodificador UTF-8 encontrar uma dessas seqüências, é possível descartar os bytes incorretos ou decodificá-los como o ponto de código Unicode para "esse caractere não existe". Naturalmente, quando você tentar codificar os caracteres como bytes, o resultado será diferente.
A solução é:
String.toByteArray
método com um conjunto de caracteres explícito.fonte
Nós só precisamos construir um novo
String
com a matriz: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/Os bytes da sequência resultante diferem dependendo do conjunto de caracteres que você usa. new String (bytes) e new String (bytes, Charset.forName ("utf-8")) e new String (bytes, Charset.forName ("utf-16")) terão todas diferentes matrizes de bytes quando você chamar String # getBytes () (dependendo do conjunto de caracteres padrão)
fonte
new String(bytes)
enew String(bytes, Charset.forName("utf-8"))
enew String(bytes, Charset.forName("utf-16"))
todos terão diferentes matrizes de bytes quando você chamarString#getBytes()
(dependendo do conjunto de caracteres padrão)char
s (e, portanto, o texto exibido) do resultadoString
diferem ao decodificar de formabytes
diferente. A conversão de volta para bytes usando a codificação padrão (useString#getBytes("charset")
para especificar o contrário) necessariamente será diferente porque converte entrada diferente. As strings não armazenam obyte[]
que foram feitas,char
s não têm uma codificação e aString
não a armazena de outra forma.Usar
new String(byOriginal)
e converter novamente embyte[]
usogetBytes()
não garante doisbyte[]
com valores iguais. Isto é devido a uma chamada paraStringCoding.encode(..)
que irá codificar oString
paraCharset.defaultCharset()
. Durante essa codificação, o codificador pode optar por substituir caracteres desconhecidos e fazer outras alterações. Portanto, o usoString.getBytes()
pode não retornar uma matriz igual à que você passou originalmente para o construtor.fonte
Por que o problema: Como alguém já especificou: Se você inicia com um byte [] e, de fato, não contém dados de texto, não há "conversão adequada". Strings são para texto, byte [] é para dados binários, e a única coisa realmente sensata a fazer é evitar a conversão entre eles, a menos que você precise.
Eu estava observando esse problema quando tentava criar o byte [] a partir de um arquivo pdf, convertendo-o em String e, em seguida, pegando o String como entrada e convertendo-o novamente em arquivo.
Portanto, verifique se a lógica de codificação e decodificação é a mesma que eu fiz. Eu codifiquei explicitamente o byte [] para Base64 e decodifiquei para criar o arquivo novamente.
Use-case: Devido a algumas limitações que eu estava tentando enviado
byte[]
norequest(POST)
e o processo foi o seguinte:Arquivo PDF >> Base64.encodeBase64 (byte []) >> String >> Solicitação de envio (POST) >> receive String >> Base64.decodeBase64 (byte []) >> create binary
Tente isso e isso funcionou para mim ..
fonte
Este trabalho é bom para mim:
Convertendo de string para byte []:
Convertendo de byte [] para string:
fonte
fonte
Eu notei algo que não está em nenhuma das respostas. Você pode converter cada um dos bytes da matriz de bytes em caracteres e colocá-los em uma matriz de caracteres. Então a string é
onde cbuf é a matriz char. Para converter de volta, faça um loop pela string que converte cada um dos caracteres em bytes para colocar em uma matriz de bytes, e essa matriz de bytes será a mesma que a primeira.fonte
javax.xml.bind.DatatypeConverter
deve fazê-lo:fonte
Aqui estão alguns métodos que convertem uma matriz de bytes em uma string. Eu testei-os, eles funcionam bem.
fonte
Apesar de
está correto, lança um
UnsupportedEncodingException
que força você a lidar com uma exceção verificada. Você pode usar como alternativa outro construtor desde o Java 1.6 para converter uma matriz de bytes emString
:Este não lança nenhuma exceção.
A conversão de volta também deve ser feita com
StandardCharsets.UTF_8
:Novamente, você evita ter que lidar com exceções verificadas.
fonte
Consegui converter a matriz de bytes em uma string com este método:
fonte
Embora a codificação base64 seja segura e possa-se argumentar "a resposta certa", cheguei aqui procurando uma maneira de converter uma matriz de bytes Java para / de uma String Java como está. Ou seja, onde cada membro da matriz de bytes permanece intacto em sua contraparte String, sem espaço extra necessário para codificação / transporte.
Esta resposta que descreve codificações transparentes de 8 bits foi muito útil para mim. eu usei
ISO-8859-1
terabytes de dados binários para converter com êxito (binário <-> String) sem os requisitos de espaço inflado necessários para uma codificação base64, portanto, é seguro para o meu caso de uso - YMMV.Isso também foi útil para explicar quando / se você deve experimentar.
fonte
fonte
Aqui o código de trabalho.
fonte
Tente especificar um conjunto de caracteres de 8 bits nas duas conversões. ISO-8859-1, por exemplo.
fonte
Leia os bytes de
String
usoByteArrayInputStream
e envolva-o comBufferedReader
Char Char em vez de Byte Stream, que converte os dados de bytes em String.A saída é:
fonte
Você pode usar o loop for simples para conversão:
fonte
fonte
Uma string é uma coleção de caracteres (16 bits não assinados). Portanto, se você converter números negativos em uma sequência, eles serão perdidos na tradução.
fonte
fonte
Use o Base64 e resolva seu problema. É muito fácil de usar. http://iharder.sourceforge.net/current/java/base64/
fonte