Java IO流体系
本文最后更新于 2025-11-11,文章内容可能已经过时。
一、分类体系
Java IO流体系主要从三个维度进行分类:
- 按处理数据单位:字节流(byte)与字符流(char)
- 按流的方向:输入流(读)与输出流(写)
- 按功能角色:节点流(基础流)与处理流(装饰流)
二、核心四大抽象类
Java IO流体系围绕四大抽象类构建:
- 字节流:InputStream(输入)、OutputStream(输出)
- 字符流:Reader(输入)、Writer(输出)
三、字节流(操作byte类型数据)
3.1 输入字节流(InputStream)
3.1.1 节点流(基础流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FileInputStream | 从文件中读取字节数据 | 读取任意本地文件(图片、文本等) | read()、read(byte[])、close() |
| ByteArrayInputStream | 从字节数组中读取数据 | 内存中操作字节数据 | read()、read(byte[])、close() |
| PipedInputStream | 从管道中读取数据 | 线程间通信 | read()、close() |
| SequenceInputStream | 将多个输入流连接成一个输入流 | 读取多个文件内容 | read()、close() |
3.1.2 处理流(装饰流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FilterInputStream | 过滤输入流的父类 | 作为其他输入流的装饰基础 | read()、skip()、mark()、reset() |
| BufferedInputStream | 提供缓冲功能,提高读取效率 | 高效读取文件内容 | read()、mark()、reset()、skip()、available() |
| DataInputStream | 读取基本数据类型(如int、float) | 读取二进制格式数据 | readInt()、readDouble()、readUTF() |
| PushbackInputStream | 可"退回"已读取数据 | 用于编译器语法、词法分析 | unread()、read() |
| ObjectInputStream | 对象反序列化 | 读取序列化对象 | readObject()、read() |
| LineNumberInputStream | 读取时获取行号 | 读取文本文件并获取行号 | readLine()、getLineNumber() |
3.2 输出字节流(OutputStream)
3.2.1 节点流(基础流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FileOutputStream | 向文件写入字节数据 | 写入任意本地文件 | write(int b)、write(byte[])、close() |
| ByteArrayOutputStream | 向字节数组写入数据 | 内存中操作字节数据 | write(int b)、write(byte[])、toByteArray() |
| PipedOutputStream | 向管道写入数据 | 线程间通信 | write(int b)、close() |
3.2.2 处理流(装饰流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FilterOutputStream | 过滤输出流的父类 | 作为其他输出流的装饰基础 | write(int b)、flush()、close() |
| BufferedOutputStream | 提供缓冲功能,提高写入效率 | 高效写入文件内容 | write(int b)、flush()、close() |
| DataOutputStream | 写入基本数据类型 | 写入二进制格式数据 | writeInt()、writeDouble()、writeUTF() |
| PrintStream | 提供方便的打印功能 | 打印格式化数据 | print()、println()、printf() |
| ObjectOutputStream | 对象序列化 | 写入序列化对象 | writeObject()、flush()、close() |
四、字符流(操作char类型数据)
4.1 字符输入流(Reader)
4.1.1 节点流(基础流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FileReader | 从文件中读取字符数据 | 读取文本文件 | read()、read(char[])、close() |
| CharArrayReader | 从字符数组中读取数据 | 内存中操作字符数据 | read()、read(char[])、close() |
| StringReader | 从字符串中读取数据 | 从字符串读取字符 | read()、read(char[])、close() |
| PipedReader | 从管道中读取字符数据 | 线程间字符通信 | read()、close() |
4.1.2 处理流(装饰流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FilterReader | 过滤字符输入流的父类 | 作为其他字符输入流的装饰基础 | read()、read(char[])、close() |
| BufferedReader | 提供缓冲功能,提高读取效率 | 高效读取文本文件 | readLine()、read()、close() |
| PushbackReader | 可"退回"已读取字符 | 用于解析器、语法分析 | unread()、read() |
| InputStreamReader | 字节流到字符流的转换器 | 将字节流转换为字符流 | read()、close() |
| LineNumberReader | 读取时获取行号 | 读取文本文件并获取行号 | readLine()、getLineNumber() |
4.2 字符输出流(Writer)
4.2.1 节点流(基础流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FileWriter | 向文件写入字符数据 | 写入文本文件 | write(int c)、write(char[])、close() |
| CharArrayWriter | 向字符数组写入数据 | 内存中操作字符数据 | write(int c)、write(char[])、toString() |
| StringWriter | 向字符串写入数据 | 将字符写入字符串 | write(int c)、write(char[])、toString() |
| PipedWriter | 向管道写入字符数据 | 线程间字符通信 | write(int c)、close() |
4.2.2 处理流(装饰流)
| 类名 | 功能描述 | 适用场景 | 核心方法 |
|---|---|---|---|
| FilterWriter | 过滤字符输出流的父类 | 作为其他字符输出流的装饰基础 | write(int c)、write(char[])、flush()、close() |
| BufferedWriter | 提供缓冲功能,提高写入效率 | 高效写入文本文件 | write(int c)、write(char[])、newLine()、flush() |
| OutputStreamWriter | 字符流到字节流的转换器 | 将字符流转换为字节流 | write(int c)、close() |
| PrintWriter | 提供方便的打印功能 | 打印格式化字符数据 | print()、println()、printf()、flush() |
五、关键概念说明
1. 字节流与字符流的区别
- 读写单位:字节流以字节(8bit)为单位,字符流以字符(16bit)为单位
- 处理对象:字节流能处理所有类型的数据(如图片、视频等),字符流只能处理字符类型的数据
- 使用场景:处理纯文本数据优先考虑字符流,其他情况使用字节流
2. 节点流与处理流
- 节点流:直接连接数据源/目的地(如文件、内存、网络)
- 处理流:包装节点流,提供额外功能(如缓冲、编码转换、对象序列化)
- 核心优势:处理流可灵活组合,按需添加功能,符合"开闭原则"
3. 字节流与字符流的桥梁
- InputStreamReader:将字节流转换为字符流(字节流→字符流)
- OutputStreamWriter:将字符流转换为字节流(字符流→字节流)
4. 流的关闭
- 所有流对象在使用后必须调用close()方法关闭,释放系统资源
- 使用try-with-resources语句可确保流被正确关闭
六、使用原则
- 优先使用字符流:处理纯文本数据时,应优先考虑字符流(如FileReader、FileWriter)
- 处理二进制数据:处理非文本数据(如图片、音频)时使用字节流(如FileInputStream、FileOutputStream)
- 使用缓冲流:在需要频繁读写时,使用缓冲流(如BufferedReader、BufferedWriter)提高效率
- 正确关闭流:始终确保流对象被正确关闭,避免资源泄漏
七、经典使用示例
1. 字符流读取文件(BufferedReader)
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
2. 字节流写入文件(BufferedOutputStream)
try (BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream("file.bin"))) {
byte[] data = "Hello, Java IO!".getBytes();
writer.write(data);
} catch (IOException e) {
e.printStackTrace();
}
3. 字符流与字节流转换
// 字节流转换为字符流
InputStream inputStream = new FileInputStream("file.bin");
Reader reader = new InputStreamReader(inputStream, "UTF-8");
// 字符流转换为字节流
OutputStream outputStream = new FileOutputStream("file.bin");
Writer writer = new OutputStreamWriter(outputStream, "UTF-8");
//#
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream("file.bin"), "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("读取文件时出错: " + e.getMessage());
}
八、总结
Java IO流体系是一个层次分明、功能强大的数据传输机制,其核心在于:
- 通过四大抽象类(
InputStream、OutputStream、Reader、Writer)构建基础 - 通过"节点流+处理流"的组合模式提供灵活的功能扩展
- 通过字节流与字符流的区分,满足不同数据处理需求
掌握Java IO流的关键在于理解其分类体系、各流类的功能特点,以及在不同场景下的合理选择。在实际开发中,应根据数据类型、性能需求和操作场景,选择合适的流类进行数据传输。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

