本文最后更新于 2025-11-11,文章内容可能已经过时。

一、分类体系

Java IO流体系主要从三个维度进行分类:

  1. 按处理数据单位:字节流(byte)与字符流(char)
  2. 按流的方向:输入流(读)与输出流(写)
  3. 按功能角色:节点流(基础流)与处理流(装饰流)

二、核心四大抽象类

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语句可确保流被正确关闭

六、使用原则

  1. 优先使用字符流:处理纯文本数据时,应优先考虑字符流(如FileReader、FileWriter)
  2. 处理二进制数据:处理非文本数据(如图片、音频)时使用字节流(如FileInputStream、FileOutputStream)
  3. 使用缓冲流:在需要频繁读写时,使用缓冲流(如BufferedReader、BufferedWriter)提高效率
  4. 正确关闭流:始终确保流对象被正确关闭,避免资源泄漏

七、经典使用示例

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流体系是一个层次分明、功能强大的数据传输机制,其核心在于:

  1. 通过四大抽象类(InputStreamOutputStreamReaderWriter)构建基础
  2. 通过"节点流+处理流"的组合模式提供灵活的功能扩展
  3. 通过字节流与字符流的区分,满足不同数据处理需求

掌握Java IO流的关键在于理解其分类体系、各流类的功能特点,以及在不同场景下的合理选择。在实际开发中,应根据数据类型、性能需求和操作场景,选择合适的流类进行数据传输。