如何将二进制数据转换为字符串并返回到Java?

问题描述:

我有一个文件中的二进制数据,我可以读入一个字节数组和进程没有问题。现在我需要通过网络连接发送部分数据作为XML文档中的元素。我的问题是,当我将数据从一个字节数组转换为一个字符串并返回到一个字节数组时,数据被损坏。我已经在一台机器上测试了这个问题,以便将问题与字符串转换隔离开来,所以我现在知道它不会被XML解析器或网络传输损坏。如何将二进制数据转换为字符串并返回到Java?

我有什么,现在是

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 

有谁知道如何转换成二进制为String和背部无数据丢失?

已经回答:谢谢萨姆。我觉得自己像个白痴。昨天我回答了这个问题,因为我的SAX解析器在抱怨。出于某种原因,当我遇到这个看似单独的问题时,我不会想到这是同样问题的新症状。

编辑:只是为了完整起见,我使用Apache CommonsCodec包中的Base64类来解决这个问题。

如果您在Base64编码它,这会变成任何数据转换成ASCII文本安全,但是Base64编码数据比一部开拓创新的数据

你如何建立你的XML文档较大?如果你使用java的内置XML类,那么应该为你处理字符串编码。

查看javax.xml和org.xml包。这就是我们用来生成XML文档的地方,它很好地处理了所有的字符串编码和解码。

---编辑:

嗯,我想我误解了这个问题。你不是想编码一个常规的字符串,而是一些任意的二进制数据集?在那种情况下,在之前的评论中提到的Base64编码可能是要走的路。我相信这是一种用XML编码二进制数据的相当标准的方法。

看到这个问题,How do you embed binary data in XML? 取而代之的是字节[]转换成字符串,然后推到XML某处,字节[]转换为通过BASE64编码(一些XML库有一个类型为你做这个)的字符串。一旦你从XML返回字符串,BASE64解码。

使用http://commons.apache.org/codec/

您的数据可能会得到搞砸由于怪异字符集种种限制和非priting人物的存在。坚持w/BASE64。

String(byte[])将数据视为默认字符编码。因此,字节如何从8位值转换为16位Java Unicode字符将不仅在操作系统之间有所不同,而且在同一台机器上使用不同代码页的不同用户之间甚至会有所不同!这个构造函数只适用于解码你自己的文本文件。不要尝试将任意字节转换为Java中的字符!

编码为base64是一个很好的解决方案。这是通过SMTP(电子邮件)发送文件的方式。 (免费)Apache Commons Codec项目将完成这项工作。

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

或者,你可以使用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 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(); 
    } 
    } 
}