Pregunta

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.Probé esto en una máquina para aislar el problema en la conversión de cadenas, por lo que ahora sé que el analizador XML o el transporte de red no lo corrompen.

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 binario a String y viceversa sin pérdida de datos?

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

EDITAR:Sólo para completar, utilicé el Base64 clase de la Apache común Códec paquete para resolver este problema.

¿Fue útil?

Solución

Si lo codifica en base64, esto convertirá cualquier dato en texto seguro ASCII, pero los datos codificados en base64 son más grandes que los datos originales.

Otros consejos

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

Codificación como base64 es una buena solución.Así es como se envían los archivos a través de SMTP (correo electrónico).El Apache (libre) Códec común El proyecto 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 utilizar Java 6 Convertidor de tipo de datos:

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 extends OutputStream> 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();
    }
  }
}

Ver esta pregunta, ¿Cómo se incrustan datos binarios en XML?En lugar de convertir el byte[] en String y luego insertarlo en XML en algún lugar, convierta el byte[] en String mediante codificación BASE64 (algunas bibliotecas XML tienen un tipo para hacer esto por usted).La decodificación BASE64 una vez que recupera la cadena de XML.

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

Es posible que sus datos se estén confundiendo debido a todo tipo de restricciones extrañas en el conjunto de caracteres y la presencia de caracteres que no son importantes.Quédese con BASE64.

¿Cómo estás construyendo tu documento XML?Si utiliza las clases XML integradas de Java, entonces la codificación de cadenas debe manejarse por usted.

Eche un vistazo a los paquetes javax.xml y org.xml.Eso es lo que usamos para generar documentos XML y maneja bastante bien toda la codificación y decodificación de cadenas.

---EDITAR:

Mmmm, creo que entendí mal el problema.¿No estás intentando codificar una cadena normal, sino algún conjunto de datos binarios arbitrarios?En ese caso, la codificación Base64 sugerida en un comentario anterior es probablemente el camino a seguir.Creo que es una forma bastante estándar de codificar datos binarios en XML.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top