25.IO (6)Reader和Writer

Reader

ReaderJavaIO库提供的另一个输入流接口。
java.io.Reader是所有字符输入流的超类,它最主要的方法是:

public int read() throws IOException;

这个方法读取字符流的下一个字符,并返回字符表示的int,范围是0~65535。如果已读到末尾,返回-1

InputStream和Reader区别

InputStream的区别是,InputStream是一个字节流,即以byte为单位读取,而Reader是一个字符流,即以char为单位读取:

InputStream Reader
字节流,以byte为单位 字符流,以char为单位
读取字节(-1,0~255):int read() 读取字符(-1,0~65535):int read()
读到字节数组:int read(byte[] b) 读到字符数组:int read(char[] c)

FileReader

FileReaderReader的一个子类,它可以打开文件并获取Reader

// 创建一个FileReader对象:
try (Reader reader = new FileReader(".\\log4j2.xml", StandardCharsets.UTF_8)) {
    int n;
    while ((n = reader.read()) != -1) {// 反复调用read()方法,直到返回-1
        System.out.println("read " +(char) n);
    }
}

Reader还提供了一次性读取若干字符并填充到char[]数组的方法:

// 创建一个FileReader对象:
try (Reader reader = new FileReader(".\\log4j2.xml", StandardCharsets.UTF_8)) {
    char[] buffer = new char[1000];//设置1000个字符的缓冲区:每次读取字符个数1000
    int n;
    while ((n = reader.read(buffer)) != -1) {
        System.out.println("read " + n + " chars.");
    }
}
#--------------输出--------------------
//read 1000 chars.
//read 444 chars.

CharArrayReader

CharArrayReader可以在内存中模拟一个Reader,它的作用实际上是把一个char[]数组变成一个Reader,这和ByteArrayInputStream非常类似:

try (Reader reader = new CharArrayReader("Hello".toCharArray())) {
}

StringReader

StringReader可以直接把String作为数据源,它和CharArrayReader几乎一样:

try (Reader reader = new StringReader("Hello")) {
}

InputStreamReader

Reader本质上是一个基于InputStreambytechar的转换器。

FileReader的源码,它在内部实际上持有一个FileInputStreamsuper(new FileInputStream(fileName), charset);

InputStreamReader就是这样一个转换器,它可以把任何InputStream转换为Reader

// 持有InputStream:
InputStream input = new FileInputStream(".\\log4j2.xml");
// 变换为Reader:
Reader reader = new InputStreamReader(input, "UTF-8");
// 也可以这么写
try (Reader reader = new InputStreamReader(new FileInputStream("src/readme.txt"), "UTF-8")) {
    // TODO:
}

Writer

Writer就是带编码转换器的OutputStream,它把char转换为byte并输出。

Writer和OutputStream的区别

OutputStream Writer
字节流,以byte为单位 字符流,以char为单位
写入字节(0~255):void write(int b) 写入字符(0~65535):void write(int c)
写入字节数组:void write(byte[] b) 写入字符数组:void write(char[] c)
无对应方法 写入Stringvoid write(String s)

向文件中写入字符流

FileWriter就是向文件中写入字符流的Writer

try (Writer writeFile = new FileWriter(".\\readme.txt", StandardCharsets.UTF_8)) {
    writeFile.write('t');// 写入单个字符
    writeFile.write("\n");
    writeFile.write("Hello World".toCharArray());// 写入char[]
    writeFile.write("\n");
    writeFile.write("java");// 写入字符串
}

在内存中创建

CharArrayWriter可以在内存中创建一个Writer,它的作用实际上是构造一个缓冲区,可以写入char,最后得到写入的char[]数组

try (CharArrayWriter writer = new CharArrayWriter()) {
    writer.write(65);
    writer.write(66);
    writer.write(67);
    char[] data = writer.toCharArray(); // { 'A', 'B', 'C' }
}

StringWriter

StringWriter也是一个基于内存的Writer,它和CharArrayWriter类似。实际上,StringWriter在内部维护了一个StringBuffer,并对外提供了Writer接口。

OutputStreamWriter

普通的Writer实际上是基于OutputStream构造的,它接收char,然后在内部自动转换成一个或多个byte,并写入OutputStream。因此,OutputStreamWriter就是一个将任意的OutputStream转换为Writer的转换器:

try (Writer writer = new OutputStreamWriter(new FileOutputStream("readme.txt"), "UTF-8")) {
    // TODO:
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容