2010-06-15 29 views
13

運行下面的(例子)代碼的Java的InputStream編碼/字符集

import java.io.*; 

public class test { 
    public static void main(String[] args) throws Exception { 
     byte[] buf = {-27}; 
     InputStream is = new ByteArrayInputStream(buf); 
     BufferedReader r = new BufferedReader(
       new InputStreamReader(is, "ISO-8859-1")); 
     String s = r.readLine(); 
     System.out.println("test.java:9 [byte] (char)" + (char)s.getBytes()[0] + 
       " (int)" + (int)s.getBytes()[0]); 
     System.out.println("test.java:10 [char] (char)" + (char)s.charAt(0) + 
       " (int)" + (int)s.charAt(0)); 
     System.out.println("test.java:11 string below"); 
     System.out.println(s); 
     System.out.println("test.java:13 string above"); 
    } 
} 

給我這個輸出

 
test.java:9 [byte] (char)? (int)63 
test.java:10 [char] (char)? (int)229 
test.java:11 string below 
? 
test.java:13 string above 

如何在線路9保持正確字節值(-27)打印?並因此獲得System.out.println(s)命令(å)的預期輸出。

回答

19

如果要保留字節值,最好不要使用讀卡器。爲了在文本中表示任意的二進制數據並稍後將其轉換爲二進制數據,您應該使用base16或base64編碼。

然而,解釋這是怎麼回事,當你調用是一個使用默認字符編碼,這顯然不包括Unicode字符U + 00E5 s.getBytes()

如果你撥打s.getBytes("ISO-8859-1")而不是s.getBytes()我懷疑你會得到正確的字節值......但依靠ISO-8859-1這是一個有點骯髒的國際海事組織。

+0

s.getBytes(「ISO-8859-1」)做的伎倆,謝謝。我只是用它來追蹤我讀取的文件內容在讀取文件到向用戶顯示數據的路徑中發生了變化。 – Tobbe 2010-06-15 13:02:41

+0

@Tobbe:很高興幫助。儘管如此,將來最好不要將它轉換成文本。當然,除非它真的是* ISO-8859-1編碼的文本文件。 – 2010-06-15 13:51:09

6

如前所述,getBytes()(無參數)使用Java平臺默認編碼,該編碼可能不是ISO-8859-1。只要打印它應該工作,只要你的終端和默認編碼匹配並支持角色。例如,在我的系統上,終端和默認的Java編碼都是UTF-8。你看到一個'?'的事實表示你不匹配或者不支持。

如果你想手動編碼爲UTF-8在系統上,做到:

String s = r.readLine(); 
byte[] utf8Bytes = s.getBytes("UTF-8"); 

它應該給一個字節數組{-61, -91}

+0

'getBytes()'使用平臺默認編碼** iff **調用無參數版本。 – 2010-06-15 09:00:48