2016-03-03 33 views
1

我有一個程序我MVN EXEC運行:JAVA(我的主要文件是在UTF-8編碼和我的系統的默認字符集爲Windows-1252)瞭解字符串編碼/解碼的Java

System.out.println(Charset.defaultCharset()); //print windows-1252 
String s = "éàè"; 
System.out.println(new String(s.getBytes(Charset.forName("UTF-8")))); //OK Print éàè 
System.out.println(new String(s.getBytes(Charset.forName("windows-1252")))); //Not OK Print ▒▒▒ 

我不明白爲什麼第一個版畫作品,根據文檔的getBytes 使用給定的charset由指定使用平臺的默認字符集的字節數組解碼構造一個新的String String構造的字符串編碼成字節序列

所以第一個打印以UTF-8編碼,然後用平臺的默認字符集windows-1252解碼,這怎麼能工作?它無法使用平臺字符集windows-1252解碼編碼的utf-8字節數組。

第二次打印是錯誤的,我不明白爲什麼。由於我的文件是用UTF-8編碼的,而平臺字符集是windows-1252,我的意圖是用windows-1252字符集編碼字符串,所以我調用s.getBytes(Charset.forName(「windows-1252」)),然後創建一個具有先前結果的字符串,但它不起作用

+0

嘗試'PrintStream out = new PrintStream(System.out,true,「windows-1252」); 通過out.println(一個或多個);' – bradimus

+0

作爲旁註,在MS-DOS默認字符集不是1252,請參見此處:https://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding .doc.html – Berger

+0

PrintStream out = new PrintStream(System.out,true,「windows-1252」);不起作用,但PrintStream out = new PrintStream(System.out,true,「utf-8」); –

回答

2

Stringéàè以UTF-8編碼爲字節八位組0xC3 0xA9 0xC3 0xA0 0xC3 0xA8。解釋爲Windows的1252那些相同的字節字節是字符串值éÃ<nbsp>è(其中<nbsp>不間斷空格字符,Unicode的編碼點U+00A0)。

在第一個示例中,您將String轉換爲上述UTF-8字節,然後使用Windows-1252而不是UTF-8將字節轉換回String。所以你應該得到一個新的StringéÃ<nbsp>è,而不是éàè。然後,您正在編寫String到控制檯,因此它被使用的是Windows 1252回字節八位字節0xC3 0xA9 0xC3 0xA0 0xC3 0xA8,這應該如果控制檯顯示的字節數顯示爲éÃ<nbsp>è(或類似於它的東西)編碼的原樣。另一方面,如果控制檯配置爲使用UTF-8,則在解釋爲UTF-8時,這些字節將顯示爲éàè

在第二個示例中,由於您正在使用Windows-1252進行編碼和解碼,並且Windows-1252支持特定字符,因此在將其寫入到原始Stringéàè安慰。如果String使用Windows-1252編碼爲字節,並且控制檯配置爲使用UTF-8,那麼爲什麼看不到éàè顯示。 Stringéàè在Windows-1252中被編碼爲字節八位組0xE9 0xE0 0xE8,它不是有效的UTF-8字節八位位組序列。

總之,你看到當你的控制檯被配置來解釋傳出字節爲UTF-8會發生,但你不給它適當的UTF-8編碼的字節輸出行爲。

+0

這是對問題的重述,而不是回答。如果你斷言他的控制檯設置爲UTF-8,那麼你應該引導。 – erickson

+0

我不只是重申了這個問題。問題是要求瞭解編碼的行爲與預期不同。我想我回答了。 –

+0

該遺體被埋葬。現在最後一段更具意義。 – erickson