Tengo que convertir una matriz de bytes a una cadena en Android, pero mi matriz de bytes contiene valores negativos.
Si convierto esa cadena de nuevo en matriz de bytes, los valores que obtengo son diferentes de los valores originales de la matriz de bytes.
¿Qué puedo hacer para obtener la conversión adecuada? El código que estoy usando para hacer la conversión es el siguiente:
// 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);
Estoy atrapado en este problema.
byte[]
para sus datos binarios yString
para su texto?Respuestas:
Su conjunto de bytes debe tener algo de codificación. La codificación no puede ser ASCII si tiene valores negativos. Una vez que descubras eso, puedes convertir un conjunto de bytes a una Cadena usando:
Hay un montón de codificaciones que se pueden utilizar, vistazo a la clase de Caracteres en los javadocs sol .
fuente
UTF-8
?String str = new String(bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
La "conversión adecuada" entre
byte[]
yString
es indicar explícitamente la codificación que desea utilizar. Si comienza con abyte[]
y, de hecho, no contiene datos de texto, no hay una "conversión adecuada".String
s son para texto,byte[]
es para datos binarios, y lo único realmente sensato es evitar la conversión entre ellos a menos que sea absolutamente necesario.Si realmente debe usar a
String
para contener datos binarios, entonces la forma más segura es usar la codificación Base64 .fuente
El problema raíz es (creo) que inconscientemente estás usando un juego de caracteres para el cual:
en algunos casos. UTF-8 es un ejemplo de tal conjunto de caracteres. Específicamente, ciertas secuencias de bytes no son codificaciones válidas en UTF-8. Si el decodificador UTF-8 encuentra una de estas secuencias, es probable que descarte los bytes ofensivos o los decodifique como el punto de código Unicode para "no tener ese carácter". Naturalmente, cuando intentes codificar los caracteres como bytes, el resultado será diferente.
La solucion es:
String.toByteArray
método con un juego de caracteres explícito.fuente
Solo necesitamos construir una nueva
String
con la matriz: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/Los bytes de la cadena resultante difieren según el juego de caracteres que utilice. la nueva Cadena (bytes) y la nueva Cadena (bytes, Charset.forName ("utf-8")) y la nueva Cadena (bytes, Charset.forName ("utf-16")) tendrán matrices de bytes diferentes cuando llame a la Cadena # getBytes () (según el juego de caracteres predeterminado)
fuente
new String(bytes)
ynew String(bytes, Charset.forName("utf-8"))
ynew String(bytes, Charset.forName("utf-16"))
todos tendrán diferentes matrices de bytes cuando se llamaString#getBytes()
(dependiendo del juego de caracteres por defecto)char
s (y por lo tanto el texto que se muestra) del resultadoString
difiere cuando se decodifica de manerabytes
diferente. La conversión de vuelta a bytes usando la codificación predeterminada (useString#getBytes("charset")
para especificar lo contrario) necesariamente diferirá porque convierte una entrada diferente. Las cadenas no almacenan el material delbyte[]
que están hechas,char
s no tienen codificación y aString
no lo almacenan de otra manera.Usar
new String(byOriginal)
y volver abyte[]
usargetBytes()
no garantiza dosbyte[]
con valores iguales. Esto se debe a una llamada a laStringCoding.encode(..)
que codificará elString
toCharset.defaultCharset()
. Durante esta codificación, el codificador podría elegir reemplazar caracteres desconocidos y hacer otros cambios. Por lo tanto, el usoString.getBytes()
podría no devolver una matriz igual como la que originalmente le pasó al constructor.fuente
¿Por qué fue el problema? Como alguien ya especificó: si comienza con un byte [] y, de hecho, no contiene datos de texto, no hay una "conversión adecuada". Las cadenas son para texto, el byte [] es para datos binarios, y lo único realmente sensato es evitar la conversión entre ellas a menos que sea absolutamente necesario.
Estaba observando este problema cuando intentaba crear un byte [] a partir de un archivo pdf y luego convertirlo a String y luego tomar el String como entrada y volver a convertirlo en archivo.
Así que asegúrese de que su lógica de codificación y decodificación sea la misma que yo. Codifiqué explícitamente el byte [] a Base64 y lo decodifiqué para crear el archivo nuevamente.
De casos de uso: Debido a algunas limitaciones que intentaba enviado
byte[]
enrequest(POST)
y el proceso fue el siguiente:Archivo PDF >> Base64.encodeBase64 (byte []) >> String >> Enviar solicitud (POST) >> recibir String >> Base64.decodeBase64 (byte []) >> crear binario
Prueba esto y esto funcionó para mí ...
fuente
Esto funciona bien para mi:
Conversión de cadena a byte []:
Conversión de byte [] a cadena:
fuente
fuente
Noté algo que no está en ninguna de las respuestas. Puede convertir cada uno de los bytes de la matriz de bytes en caracteres y colocarlos en una matriz de caracteres. Entonces la cuerda es
donde cbuf es la matriz de caracteres. Para volver a convertir, recorra la cadena convirtiendo cada uno de los caracteres en bytes para colocar en una matriz de bytes, y esta matriz de bytes será la misma que la primera.fuente
javax.xml.bind.DatatypeConverter
Deberías hacerlo:fuente
Aquí hay algunos métodos que convierten una matriz de bytes en una cadena. Los he probado, funcionan bien.
fuente
Aunque
es correcto, arroja un
UnsupportedEncodingException
que te obliga a lidiar con una excepción marcada. Como alternativa, puede usar otro constructor desde Java 1.6 para convertir una matriz de bytes enString
:Este no arroja ninguna excepción.
La conversión de regreso también debe hacerse con
StandardCharsets.UTF_8
:Nuevamente, evitas tener que lidiar con excepciones marcadas.
fuente
Logré convertir byte array a una cadena con este método:
fuente
Si bien la codificación base64 es segura y se podría argumentar "la respuesta correcta", llegué aquí buscando una manera de convertir una matriz de bytes de Java a / desde una cadena de Java tal como está. Es decir, donde cada miembro de la matriz de bytes permanece intacto en su contraparte de cadena, sin espacio adicional requerido para la codificación / transporte.
Esta respuesta que describe codificaciones transparentes de 8 bits fue muy útil para mí. Utilicé
ISO-8859-1
en terabytes de datos binarios para convertir con éxito (Binary <-> String) sin los requisitos de espacio inflado necesarios para una codificación base64, por lo que es seguro para mi caso de uso: YMMV.Esto también fue útil para explicar cuándo / si debe experimentar.
fuente
fuente
Aquí el código de trabajo.
fuente
Intente especificar un juego de caracteres de 8 bits en ambas conversiones. ISO-8859-1 por ejemplo.
fuente
Lea los bytes del
String
usoByteArrayInputStream
y envuélvalos conBufferedReader
Char Stream en lugar de Byte Stream, que convierte los datos de bytes en String.Salida es:
fuente
Puede usar simple for loop para la conversión:
fuente
fuente
Una cadena es una colección de caracteres (16 bits sin signo). Entonces, si va a convertir números negativos en una cadena, se perderán en la traducción.
fuente
fuente
Usa Base64 y resuelve tu problema. Es demasiado fácil de usar. http://iharder.sourceforge.net/current/java/base64/
fuente