Java 为什么是字符流?
我理解Java字符流包装字节流,以便根据系统默认值或其他特定定义的字符集解释底层字节流 我的系统默认字符集是UTF-8 如果我使用Java 为什么是字符流?,java,iostream,java-io,Java,Iostream,Java Io,我理解Java字符流包装字节流,以便根据系统默认值或其他特定定义的字符集解释底层字节流 我的系统默认字符集是UTF-8 如果我使用FileReader读取文本文件,一切看起来都正常,因为默认字符集用于解释底层InputStreamReader中的字节。如果我明确定义了一个InputStreamReader,以UTF-16的形式读取UTF-8编码的文本文件,那么一切看起来都很奇怪。使用像FileInputStream这样的字节流,并将其输出重定向到System.out,一切看起来都很好 所以我的问
FileReader
读取文本文件,一切看起来都正常,因为默认字符集用于解释底层InputStreamReader
中的字节。如果我明确定义了一个InputStreamReader
,以UTF-16的形式读取UTF-8编码的文本文件,那么一切看起来都很奇怪。使用像FileInputStream
这样的字节流,并将其输出重定向到System.out,一切看起来都很好
所以我的问题是,
- 为什么使用字符流很有用
- 为什么我要使用字符流而不是直接使用字节流
- 什么时候定义一个特定的字符集有用
- 一个
输入流
读取字节,而读取器
读取字符。由于字节映射到字符的方式,在创建InputStreamReader
时,需要指定字符集(或编码),默认为平台字符集。在读取/写入包含可能大于127个字符的文本时,使用字符流。读取/写入二进制数据时,请使用字节流
如果愿意,您可以将文本作为二进制读取,但除非您做了大量的假设,否则它几乎不会给您带来太多好处。处理字符串的代码应该只“思考”文本——例如,逐行读取输入源,您不想关心该源的性质 但是,存储通常是面向字节的-因此您需要在源的面向字节视图(由
InputStream
封装)和源的面向字符视图(由Reader
封装)之间创建转换
因此,计算输入源中文本行数的方法应该采用读取器
参数。如果要计算两个文件中的文本行数,其中一个文件编码为UTF-8,另一个文件编码为UTF-16,则需要为每个文件在FileInputStream
周围创建inputstream
,每次指定适当的编码
(就我个人而言,我会完全避免使用
FileReader
,因为它不允许您指定编码,所以在我看来它是无用的)。+1因为我提到FileReader
是如此的无用。:)为什么FileInputStream
会像InputStreamReader
一样解释我的简单UTF-8编码文本?是不是正如彼得·劳瑞所说的那样——只有在我的文本中添加晦涩的字符时,我才会注意到区别?@WulfgarPro:不是。它读取原始字节。如果将这些原始字节发送到System.out,System.out(打印流)将使用默认的平台编码将它们输出到控制台。@JB:更准确地说,它将它们输出到控制台而不使用任何编码,并且控制台希望配置为使用与“默认字符编码”相同的编码。