2010-06-15 78 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