读取多字节字符时 InputStream 和 InputStreamReader 之间的区别

2022-09-01 12:02:29

和 之间的区别在于,读作 为 ,而读作 。例如,如果文件中的文本是 ,则它们都可以正常工作。但是,如果文本是 ,它由一个和两个汉字组成,则不起作用。InputStreamInputStreamReaderInputStreambyteInputStreamReadercharabca你们aInputStream

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

InputStreamReader 如何识别字符?

a是一个字节,但一个中文字符是两个字节。它是读作一个字节,将另一个字符识别为两个字节,还是对于此文本中的每个字符,是否将其读作两个字节?aInputStreamReader


答案 1

A 读取原始八位字节(8 位)数据。在 Java 中,该类型等效于 C 中的类型。在 C 中,此类型可用于表示字符数据或二进制数据。在Java中,该类型与C类型具有更大的相似性。InputStreambytecharcharwchar_t

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

Java 中的字符编码 API 包含执行此转换的算法。您可以在此处找到 Oracle JRE 支持的编码列表。如果您想了解ICU项目在实践中如何工作的内部因素,那么ICU项目是一个很好的起点。

正如Alexander Pogrebnyak所指出的,你几乎总是应该明确地提供编码。未指定编码的方法依赖于 JRE 默认值,该默认值依赖于操作系统和用户设置。bytechar


答案 2

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

Reader reader =
   new InputStreamReader(
       new FileInputStream( "/path/to/file" ),
       "UTF-8" // most likely that the encoding of the file
   )

如果没有提示,它将使用您的平台默认编码,在许多情况下,这不是您想要的。

此链接对编码有很好的解释:http://www.joelonsoftware.com/articles/Unicode.html


推荐