2012-02-04 64 views
1

如果我有一些二進制數據D並將其轉換爲字符串S.我期望將它轉換回二進制我會得到D.但它是錯誤的。將二進制數據轉換爲字符串

public class A { 
    public static void main(String[] args) throws IOException { 
     final byte[] bytes = new byte[]{-114, 104, -35};// In hex: 8E 68 DD 
     System.out.println(bytes.length);    //prints 3 
     System.out.println(new String(bytes, "UTF-8").getBytes("UTF-8").length); //prints 7 
    } 
} 

爲什麼會發生這種情況?

+0

你試圖強制任意的二進制數據到一個字符串?爲什麼? – Jesper 2012-02-04 20:22:00

+0

(如果*由於某種原因必須隱藏字符串中的二進制數,則需要使用提供字節和字符之間的一對一映射的編碼; ISO-8859-1將是明顯的選擇UTF-8的字節序列不代表有效字符。) – bobince 2012-02-05 09:29:21

回答

2

將字節數組轉換爲字符串並再次返回不是一對一的映射操作。讀取docs時,字符串implmentation使用CharsetDecoder將傳入的字節數組轉換爲unicode。輸入字節數組中的第一個字節和最後一個字節不得映射爲有效的Unicode字符,因此它將替換爲一些replacement string

+0

好點。但這似乎很奇怪。爲什麼它應該使用一些魔術替代字符串而不是拋出異常? – 2012-02-04 20:11:54

+0

我猜CharsetDecoder遇到一個不可映射的字符時拋出一個異常是可能的,但是默認的String實現使用一個默認錯誤字符的較不易變的選項。我敢打賭你可以自己使用CharsetDecoder來控制Byte [] <->字符串轉換。 – 2012-02-04 20:27:27

1

這很可能是您轉換爲字符串的字節實際上並不構成有效的字符串。如果java無法弄清楚每個字節的意思,它會嘗試修復它們。這意味着當你轉換回字節數組時,它不會和你啓動時一樣。如果你嘗試使用一組有效的字節,那麼你應該會更成功。

+0

是的。但我至少除了在這種情況下得到例外。 – 2012-02-04 20:03:42

+0

行爲是可配置的 - 您可以忽略,替換或錯誤。請參閱http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/charset/CharsetDecoder.html,特別是有關CodingErrorAction類 – DNA 2012-02-04 20:33:23

+0

@DNA的位,謝謝您的好意。 – 2012-02-04 20:44:21

0

使用UTF-8編碼無法將您的數據解碼爲有效的Unicode字符。看看解碼後的字符串。它由3個字符組成:0xFFFD0x00680xFFFD。首先和最後是「 」 - Unicode replacement characters。我認爲你需要選擇其他編碼。即「CP866」生成有效的字符串並將其轉換回相同的數組。

相關問題