Java 读取多字节字符时InputStream和InputStreamReader之间的差异

Java 读取多字节字符时InputStream和InputStreamReader之间的差异,java,character-encoding,io,Java,Character Encoding,Io,InputStream和InputStreamReader之间的区别在于InputStream读作byte,而InputStreamReader读作char。例如,如果文件中的文本是abc,则两者都可以正常工作。但是如果文本是a你们,由一个a和两个汉字组成,则InputStream不起作用 所以我们应该使用InputStreamReader,但我的问题是: InputStreamReader如何识别字符? a是一个字节,但汉字是两个字节。它是否将a读取为一个字节,并将另一个字符识别为两个字节,或

InputStream
InputStreamReader
之间的区别在于
InputStream
读作
byte
,而
InputStreamReader
读作
char
。例如,如果文件中的文本是
abc
,则两者都可以正常工作。但是如果文本是
a你们
,由一个
a
和两个汉字组成,则
InputStream
不起作用

所以我们应该使用
InputStreamReader
,但我的问题是:

InputStreamReader如何识别字符?


a
是一个字节,但汉字是两个字节。它是否将
a
读取为一个字节,并将另一个字符识别为两个字节,或者对于本文中的每个字符,
InputStreamReader是否将其读取为两个字节?

您必须通过提供二进制文件写入的字符集,给读者一个提示。例如

Reader reader =
   new InputStreamReader(
       new FileInputStream( "/path/to/file" ),
       "UTF-8" // most likely that the encoding of the file
   )
如果没有提示,它将使用您的平台默认编码,在许多情况下,这不是您想要的


这个链接对编码有很好的解释:

一个
InputStream
读取原始八位字节(8位)数据。在Java中,
byte
类型相当于C中的
char
类型。在C中,此类型可用于表示字符数据或二进制数据。在Java中,
char
类型与C
wchar\u t
类型具有更大的相似性

然后,
InputStreamReader
会将数据从某种编码转换为UTF-16。如果“a”你们" 在磁盘上被编码为UTF-8,它将是字节序列
61 E4 BD A0 E4 BB AC
。当您使用UTF-8编码将
InputStream
传递给
InputStreamReader
时,它将被读取为字符序列
0061 4F60 4EEC

Java中的字符编码API包含执行此转换的算法。您可以找到Oracle JRE支持的编码列表。如果您想了解其在实践中的工作原理,可以从中开始。

正如Alexander Pogrebnyak所说,您几乎应该始终明确地提供编码。
byte
-to-
char
不指定编码的方法依赖于,这取决于操作系统和用户设置