¿Cómo se convierten datos binarios a cadenas y viceversa en Java?

Tengo datos binarios en un archivo que puedo leer en una matriz de bytes y procesar sin problemas. Ahora necesito enviar partes de los datos a través de una conexión de red como elementos en un documento XML. Mi problema es que cuando convierto los datos de una matriz de bytes a una Cadena y vuelvo a una matriz de bytes, los datos se corrompen. He probado esto en una máquina para aislar el problema de la conversión de cadena, así que ahora sé que no se está corrompiendo con el analizador XML o el transporte de red.

Lo que tengo ahora es

byte[] buffer = ...; // read from file // a few lines that prove I can process the data successfully String element = new String(buffer); byte[] newBuffer = element.getBytes(); // a few lines that try to process newBuffer and fail because it is not the same data anymore 

¿Alguien sabe cómo convertir binarios a cadenas y viceversa sin pérdida de datos?

Respondido: Gracias Sam. Me siento como un idiota. Ayer respondí esto porque mi analizador SAX se quejaba. Por alguna razón, cuando me encontré con este tema aparentemente separado, no se me ocurrió que era un nuevo síntoma del mismo problema.

EDITAR: solo para completar, utilicé la clase Base64 del paquete Apache Commons Codec para resolver este problema.

Si codifica en base64, esto convertirá cualquier dato en texto seguro, pero los datos codificados en base64 son más grandes que los datos de orignal

String (byte []) trata los datos como la encoding de caracteres predeterminada. Entonces, cómo se convierten los bytes de los valores de 8 bits a los caracteres de Java Unicode de 16 bits variará no solo entre los sistemas operativos, sino que incluso puede variar entre diferentes usuarios que utilizan diferentes páginas de códigos en la misma máquina. Este constructor solo sirve para decodificar uno de tus propios archivos de texto. ¡No intente convertir bytes arbitrarios a caracteres en Java!

La encoding como base64 es una buena solución. Así es como los archivos se envían a través de SMTP (correo electrónico). El proyecto (gratuito) Apache Commons Codec hará el trabajo.

 byte[] bytes = loadFile(file); //all chars in encoded are guaranteed to be 7-bit ASCII byte[] encoded = Base64.encodeBase64(bytes); String printMe = new String(encoded, "US-ASCII"); System.out.println(printMe); byte[] decoded = Base64.decodeBase64(encoded); 

Alternativamente, puede usar Java 6 DatatypeConverter :

 import java.io.*; import java.nio.channels.*; import javax.xml.bind.DatatypeConverter; public class EncodeDecode { public static void main(String[] args) throws Exception { File file = new File("/bin/ls"); byte[] bytes = loadFile(file, new ByteArrayOutputStream()).toByteArray(); String encoded = DatatypeConverter.printBase64Binary(bytes); System.out.println(encoded); byte[] decoded = DatatypeConverter.parseBase64Binary(encoded); // check for (int i = 0; i < bytes.length; i++) { assert bytes[i] == decoded[i]; } } private static  T loadFile(File file, T out) throws IOException { FileChannel in = new FileInputStream(file).getChannel(); try { assert in.size() == in.transferTo(0, in.size(), Channels.newChannel(out)); return out; } finally { in.close(); } } } 

Consulte esta pregunta, ¿cómo incrusta datos binarios en XML? En lugar de convertir el byte [] en String y luego insertar XML en alguna parte, convierta el byte [] en un String a través de la encoding BASE64 (algunas bibliotecas XML tienen un tipo para hacer esto por usted). La deencoding BASE64 una vez que recuperas el String de XML.

Use http://commons.apache.org/codec/

Es posible que los datos se dañen debido a todo tipo de restricciones de conjunto de caracteres y la presencia de personajes no prudentes. Stick w / BASE64.

¿Cómo estás construyendo tu documento XML? Si utiliza las clases XML integradas de Java, entonces la encoding de cadena se debe manejar por usted.

Eche un vistazo a los paquetes javax.xml y org.xml. Eso es lo que usamos para generar documentos XML, y maneja toda la encoding y deencoding de cadenas bastante bien.

—EDITAR:

Hmm, creo que malentendí el problema. ¿No estás tratando de codificar una cadena normal, sino un conjunto de datos binarios arbitrarios? En ese caso, la encoding Base64 sugerida en un comentario anterior es probablemente el camino a seguir. Creo que es una forma bastante estándar de encoding de datos binarios en XML.