2008-08-21 85 views
27

我有一個文件中的二進制數據,我可以讀入一個字節數組和進程沒有問題。現在我需要通過網絡連接發送部分數據作爲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類來解決這個問題。

回答

19

如果您在Base64編碼它,這會變成任何數據轉換成ASCII文本安全,但是Base64編碼數據比一部開拓創新的數據

0

你如何建立你的XML文檔較大?如果你使用java的內置XML類,那麼應該爲你處理字符串編碼。

查看javax.xml和org.xml包。這就是我們用來生成XML文檔的地方,它很好地處理了所有的字符串編碼和解碼。

---編輯:

嗯,我想我誤解了這個問題。你不是想編碼一個常規的字符串,而是一些任意的二進制數據集?在那種情況下,在之前的評論中提到的Base64編碼可能是要走的路。我相信這是一種用XML編碼二進制數據的相當標準的方法。

2

看到這個問題,How do you embed binary data in XML? 取而代之的是字節[]轉換成字符串,然後推到XML某處,字節[]轉換爲通過BASE64編碼(一些XML庫有一個類型爲你做這個)的字符串。一旦你從XML返回字符串,BASE64解碼。

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

您的數據可能會得到搞砸由於怪異字符集種種限制和非priting人物的存在。堅持w/BASE64。

35

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(); 
    } 
    } 
} 
相關問題