Java字符流Reader和Writer类用法详解(附带实例)
在 Java 中,I/O 流(输入/输出流)是用于进行数据输入和输出的机制。
I/O 流是 Java 程序与外部设备(如文件、网络、控制台等)进行数据交互的重要方式。通过 I/O 流,我们可以从外部设备读取数据到程序中,也可以将程序中的数据输出到外部设备。
Java 的 I/O 流以字节流和字符流两种方式进行数据的传输。其中,字符流以字符为单位进行数据传输,用于处理文本数据,适用于读写文本文件。字符流主要由 Reader 类和 Writer 类及其子类组成。

图 1 字符输入流类的继承层次
Reader 有很多子类,这些类的说明如下表所示:
Reader 类定义了很多方法,影响着字符输入流的行为,主要方法如下:
上述所有方法都可能会抛出 IOException,因此使用时要注意处理异常。

图 2 字符输出流类的继承层次
它有很多子类,这些类的说明如下表所示:
Writer 类定义了很多方法,影响着字符输出流的行为,主要方法如下:
上述所有方法都声明了抛出 IOException,因此使用时要注意处理异常。
Reader 和 Writer 都实现了 AutoCloseable 接口,可以使用自动资源管理技术自动关闭它们。
复制文件时,数据源是文件,所以会用到文件输入流 FileReader;数据目的地也是文件,所以会用到文件输出流 FileWriter。
FileReader 和 FileWriter 的主要方法都继承自 Reader 和 Writer,这里不再赘述。下面介绍它们的构造方法。
FileReader 构造方法主要有:
FileWriter 构造方法主要有:
接下来实现将当前项目的 data 目录下的“build.txt”文件内容复制为“build-副本.txt”。参考代码如下:
I/O 流是 Java 程序与外部设备(如文件、网络、控制台等)进行数据交互的重要方式。通过 I/O 流,我们可以从外部设备读取数据到程序中,也可以将程序中的数据输出到外部设备。
Java 的 I/O 流以字节流和字符流两种方式进行数据的传输。其中,字符流以字符为单位进行数据传输,用于处理文本数据,适用于读写文本文件。字符流主要由 Reader 类和 Writer 类及其子类组成。
Java字符流
1) 字符输入流
字符输入流的根类是 Reader,这类流以 16 位的 Unicode 编码表示的字符为基本处理单位,如下图所示。
图 1 字符输入流类的继承层次
Reader 有很多子类,这些类的说明如下表所示:
类 | 描述 |
---|---|
FileReader | 文件输入流 |
CharArrayReader | 面向字符数组的输入流 |
PipedReader | 管道输入流,用于两个线程之间的数据传递 |
FilterReader | 过滤输入流,它是一个装饰器,用于扩展其他输入流 |
BufferedReader | 缓冲区输入流,它也是装饰器,它不是 FilterReader 的子类 |
InputStreamReader | 把字节流转换为字符流,它也是一个装饰器,是 FileReader 的父类 |
Reader 类定义了很多方法,影响着字符输入流的行为,主要方法如下:
- int read():读取一个字符,返回值在 0~65535(0x00~0xffff)之间。如果已经到达流末尾,则返回值 -1。
- int read(char[] cbuf):将字符读入到数组cbuf中,返回值为实际读取的字符的数量。如果已经到达流末尾,则返回值-1。
- int read(char[]cbuf, int off, int len):最多读取 len 个字符,数据放到以索引 off 开始的字符数组 cbuf 中,将读取的第一个字符存储在元素 cbuf[off] 中,下一个存储在元素 cbuf[off+1]中,依次类推。返回值为实际读取的字符的数量。如果已经到达流末尾,则返回值 -1。
- void close():流操作完毕后必须关闭。
上述所有方法都可能会抛出 IOException,因此使用时要注意处理异常。
2) 字符输出流
字符输出流的根类是 Writer,这类流以 16 位的 Unicode 编码表示的字符为基本处理单位,如下图所示:
图 2 字符输出流类的继承层次
它有很多子类,这些类的说明如下表所示:
类 | 描述 |
---|---|
FileWriter | 文件输出流 |
CharArrayWriter | 面向字符数组的输出流 |
PipedWriter | 管道输出流,用于两个线程之间的数据传递 |
FilterWriter | 过滤输出流,它是一个装饰器,用于扩展其他输出流 |
BufferedWriter | 缓冲区输出流,它也是装饰器,它不是 FilterWriter 的子类 |
OutputStreamWriter | 把字节流转换为字符流,它也是一个装饰器,是 FileWriter 的父类 |
Writer 类定义了很多方法,影响着字符输出流的行为,主要方法如下:
- void write(int c):将整数值为c的字符写入到输出流,c是int类型,占有32位,写入时只写入c的16个低位,c的16个高位将被忽略。
- void write(char[] cbuf):将字符数组cbuf写入到输出流。
- void write(char[] cbuf, int off, int len):把字符数组cbuf中从索引off开始、长度为len的字符写入到输出流。
- void write(String str):将字符串str中的字符写入输出流。
- void write(String str, int off, int len):将字符串str中从索引off开始的len个字符写入输出流。
- void flush():刷空输出流,并输出所有被缓存的字符。由于某些流支持缓存功能,该方法将把缓存中的所有内容强制输出到流中。
- void close():流操作完毕后必须关闭。
上述所有方法都声明了抛出 IOException,因此使用时要注意处理异常。
Reader 和 Writer 都实现了 AutoCloseable 接口,可以使用自动资源管理技术自动关闭它们。
Java字符流复制文本文件
复制文本文件是一种常见的文件操作,它可以将一个文本文件的内容完全复制到另一个文件中。复制文件时,数据源是文件,所以会用到文件输入流 FileReader;数据目的地也是文件,所以会用到文件输出流 FileWriter。
FileReader 和 FileWriter 的主要方法都继承自 Reader 和 Writer,这里不再赘述。下面介绍它们的构造方法。
FileReader 构造方法主要有:
- FileReader(String fileName):创建 FileReader 对象,fileName 是文件名。如果文件不存在,则抛出 FileNotFoundException 异常。
- FileReader(File file):通过 File 对象创建 FileReader 对象。如果文件不存在,则抛出 FileNotFoundException 异常。
FileWriter 构造方法主要有:
- FileWriter(String fileName):通过指定文件名 fileName 创建 FileWriter 对象。如果 fileName 文件存在,但是一个目录或文件无法打开,则抛出 FileNotFoundException 异常。
- FileWriter(String fileName,boolean append):通过指定文件名 fileName 创建 FileWriter 对象,如果 append 参数为 true,则将字符写入文件末尾处,而不是写入文件开始处。如果fileName文件存在,但是一个目录或文件无法打开,则抛出 FileNotFoundException 异常。
- FileWriter(File file):通过 File 对象创建 FileWriter 对象。如果 file 文件存在,但是一个目录或文件无法打开,则抛出 FileNotFoundException 异常。
- FileWriter(File file, boolean append):通过 File 对象创建 FileWriter 对象,如果 append 参数为 true,则将字符写入文件末尾处,而不是写入文件开始处。如果 file 文件存在,但是一个目录或文件无法打开,则抛出 FileNotFoundException 异常。
接下来实现将当前项目的 data 目录下的“build.txt”文件内容复制为“build-副本.txt”。参考代码如下:
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyTextFileExample { public static void main(String[] args) { try (FileReader in = new FileReader("data/build.txt"); FileWriter out = new FileWriter("data/build - 副本.txt")) { // 准备一个缓冲区 char[] buffer = new char[10]; // 首先读取一次 int len = in.read(buffer); while (len != -1) { // 开始写入数据 out.write(buffer, 0, len); // 再读取一次 len = in.read(buffer); } } catch (IOException e) { e.printStackTrace(); System.out.println("复制失败!"); } System.out.println("复制完成。"); } }
相关文章
- Java字符流(Reader和Writer)的用法
- Java字符流的使用:字符输入/输出流、字符文件和字符缓冲区的输入/输出流
- Java字符流FileReader和FileWriter的用法(附带实例)
- Java字节流和字符流的区别,如何区分输入流和输出流?
- Java字节流的使用:字节输入/输出流、文件输入/输出流、字节数组输入/输出流
- Java字节流用法详解
- Java字节流InputStream和OutputStream详解(附带实例)
- Java字符串大小写转换(toLowerCase()和toUpperCase())
- Java字符串的替换(replace()、replaceFirst()和replaceAll())
- Java字符串替换实例