type
status
date
slug
summary
tags
category
icon
password
Property
Reader
Reader
是Java的IO库提供的另一个输入流接口。和InputStream
的区别是,InputStream
是一个字节流,即以byte
为单位读取,而Reader
是一个字符流,即以char
为单位读取:java.io.Reader
是所有字符输入流的超类,它最主要的方法是:这个方法读取字符流的下一个字符,并返回字符表示的
int
,范围是0
~65535
。如果已读到末尾,返回-1
。FileReader
是Reader
的一个子类,它可以打开文件并获取Reader
。完整地读取一个FileReader
的所有字符:如果读取一个纯ASCII编码的文本文件,上述代码工作是没有问题的。但如果文件中包含中文,就会出现乱码,因为
FileReader
默认的编码与系统相关,例如,Windows系统的默认编码可能是GBK
,打开一个UTF-8
编码的文本文件就会出现乱码。要避免乱码问题,需要在创建
FileReader
时指定编码:和
InputStream
类似,Reader
也是一种资源,需要保证出错的时候也能正确关闭,所以我们需要用try (resource)
来保证Reader
在无论有没有IO错误的时候都能够正确地关闭:Reader
还提供了一次性读取若干字符并填充到char[]
数组的方法:它返回实际读入的字符个数,最大不超过
char[]
数组的长度。返回-1
表示流结束。利用这个方法,我们可以先设置一个缓冲区,然后,每次尽可能地填充缓冲区:
CharArrayReader
CharArrayReader
可以在内存中模拟一个Reader
,它的作用实际上是把一个char[]
数组变成一个Reader
,这和ByteArrayInputStream
非常类似:StringReader
StringReader
可以直接把String
作为数据源,它和CharArrayReader
几乎一样:InputStreamReader
Reader
和InputStream
有什么关系?除了特殊的
CharArrayReader
和StringReader
,普通的Reader
实际上是基于InputStream
构造的,因为Reader
需要从InputStream
中读入字节流(byte
),然后,根据编码设置,再转换为char
就可以实现字符流。如果我们查看FileReader
的源码,它在内部实际上持有一个FileInputStream
。既然
Reader
本质上是一个基于InputStream
的byte
到char
的转换器,那么,如果已经有一个InputStream
,想把它转换为Reader
,是完全可行的。InputStreamReader
就是这样一个转换器,它可以把任何InputStream
转换为Read
:构造
InputStreamReader
时,我们需要传入InputStream
,还需要指定编码,就可以得到一个Reader
对象。上述代码可以通过try (resource)
更简洁地改写如下:上述代码实际上就是
FileReader
的一种实现方式。使用
try (resource)
结构时,当我们关闭Reader
时,它会在内部自动调用InputStream
的close()
方法,所以,只需要关闭最外层的Reader
对象即可。使用InputStreamReader,可以把一个InputStream转换成一个Reader。
Writer
Reader
是带编码转换器的InputStream
,它把byte
转换为char
,而Writer
就是带编码转换器的OutputStream
,它把char
转换为byte
并输出。Writer
和OutputStream
的区别如下:Writer
是所有字符输出流的超类,它提供的方法主要有:- 写入一个字符(0~65535):
void write(int c)
;
- 写入字符数组的所有字符:
void write(char[] c)
;
- 写入String表示的所有字符:
void write(String s)
。
FileWriter
FileWriter
就是向文件中写入字符流的Writer
。它的使用方法和FileReader
类似:CharArrayWriter
CharArrayWriter
可以在内存中创建一个Writer
,它的作用实际上是构造一个缓冲区,可以写入char
,最后得到写入的char[]
数组,这和ByteArrayOutputStream
非常类似:StringWriter
StringWriter
也是一个基于内存的Writer
,它和CharArrayWriter
类似。实际上,StringWriter
在内部维护了一个StringBuffer
,并对外提供了Writer
接口。OutputStreamWriter
除了
CharArrayWriter
和StringWriter
外,普通的Writer实际上是基于OutputStream
构造的,它接收char
,然后在内部自动转换成一个或多个byte
,并写入OutputStream
。因此,OutputStreamWriter
就是一个将任意的OutputStream
转换为Writer
的转换器:上述代码实际上就是
FileWriter
的一种实现方式。这和InputStreamReader
是一样的。