Java InputStream编码/ charset

运行以下(示例)代码

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字符串如下
 ?
 test.java:13字符串上面

如何在第9行打印输出中保留正确的字节值(-27)? 并因此接收System.out.println(s)命令(å)的预期输出。

如果要保留字节值,请不要使用Reader,理想情况下。 要在文本中表示任意二进制数据并在以后将其转换回二进制数据,应使用base16或base64编码。

但是,为了解释发生了什么,当你调用使用默认字符编码的s.getBytes() ,显然不包含Unicode字符U + 00E5。

如果你到处调用s.getBytes("ISO-8859-1")而不是s.getBytes()我怀疑你会得到正确的字节值…但依赖于ISO-8859-1这有点脏IMO。

如上所述, getBytes() (无参数)使用Java平台默认编码,可能不是ISO-8859-1。 如果你的终端和默认编码匹配并支持角色,只需打印就可以了。 例如,在我的系统上,终端和默认Java编码都是UTF-8。 你看到’?’的事实 表示您的不匹配或不支持。

如果要在系统上手动编码为UTF-8,请执行以下操作:

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

它应该给出一个带有{-61, -91}的字节数组。