目录

0. 分析Java IO 流体系架构

0.1 IO 流体系核心分类逻辑

0.2 四大顶级抽象基类(蓝色框)

0.3 核心实现类详解(红色框)

0.3.1 字节流实现类

字节输入流

字节输出流

0.3.2 字符流实现类

字符输入流

字符输出流

1. 字节流体系(以 byte 为单位,万

能流)

1.1 字节输入流(InputStream 分支)

1.1.1 顶级抽象类:InputStream

1.1.2 基础节点流:FileInputStream

1.1.3 缓冲处理流:BufferedInputStream

1.1.4 数据处理流:DataInputStream

1.1.5 对象处理流:ObjectInputStream

1.2 字节输出流(OutputStream 分支)

1.2.1 顶级抽象类:OutputStream

1.2.2 基础节点流:FileOutputStream

1.2.3 缓冲处理流:BufferedOutputStream

1.2.4 打印处理流:PrintStream

1.2.5 数据处理流:DataOutputStream

1.2.6 对象处理流:ObjectOutputStream

2. 字符流体系(以 char 为单位,专门处理文本)

2.1 字符输入流(Reader 分支)

2.1.1 顶级抽象类:Reader

2.1.2 转换流:InputStreamReader

2.1.3 基础节点流:FileReader

2.1.4 缓冲处理流:BufferedReader

2.2 字符输出流(Writer 分支)

2.2.1 顶级抽象类:Writer

2.2.2 转换流:OutputStreamWriter

2.2.3 基础节点流:FileWriter

2.2.4 缓冲处理流:BufferedWriter

2.2.5 打印处理流:PrintWriter

3. IO 流体系总结与选型建议

3.1 类的层级关系全景

3.2 选型原则(按场景选择)


0. 分析Java IO 流体系架构

0.1 IO 流体系核心分类逻辑

Java IO 流有两个核心分类维度,构成了图中的四大基础分支:

分类维度 分类项 核心说明
数据处理单位 字节流 以字节(byte)为单位处理数据,万能流,可处理所有类型文件(图片、视频、文本、压缩包等)
字符流 以字符(char)为单位处理数据,专门处理文本,自动处理编码转换,规避文本乱码问题
数据流向 输入流 从数据源(文件 / 网络等)读取数据到程序,对应「读」操作
输出流 从程序写入数据到目标位置,对应「写」操作

0.2 四大顶级抽象基类(蓝色框)

这四个类是对应流分支的顶级父类,均为抽象类,无法直接实例化,定义了对应流的通用核心方法。

表格

抽象类 所属分支 核心定位
InputStream 字节输入流 所有字节输入流的父类,定义字节读取的通用方法
OutputStream 字节输出流 所有字节输出流的父类,定义字节写入的通用方法
Reader 字符输入流 所有字符输入流的父类,定义字符读取的通用方法
Writer 字符输出流 所有字符输出流的父类,定义字符写入的通用方法

0.3 核心实现类详解(红色框)

以下是可直接实例化使用的实现类,按分支拆解核心作用与使用场景。

0.3.1 字节流实现类
字节输入流
  • FileInputStream:文件字节输入流,最基础的字节流,用于从本地文件读取字节数据,是文件二进制读取的基础实现。
  • BufferedInputStream:缓冲字节输入流,基于装饰器模式实现,内置缓冲区,大幅减少磁盘 IO 次数,提升字节读取效率,需包装基础 InputStream 使用。
  • DataInputStream:数据字节输入流,支持按 Java 基本数据类型(int/long/float 等)读取数据,保证数据读写的平台无关性。
  • ObjectInputStream:对象字节输入流,用于对象反序列化,将持久化的字节数据还原为 Java 对象,要求对象必须实现Serializable接口。
字节输出流
  • FileOutputStream:文件字节输出流,最基础的字节输出流,用于向本地文件写入字节数据,支持覆盖 / 追加两种写入模式。
  • BufferedOutputStream:缓冲字节输出流,内置缓冲区,减少磁盘 IO 次数,提升写入效率,仅在flush()/close()时会将缓冲区数据写入目标。
  • PrintStream:打印字节流,最经典的应用是System.out,提供print/println等便捷方法,支持打印各类数据类型,不会抛出 IOException,支持自动刷新。
  • DataOutputStream:数据字节输出流,与DataInputStream配对,用于写入 Java 基本数据类型,实现基础类型的序列化存储。
  • ObjectOutputStream:对象字节输出流,与ObjectInputStream配对,用于对象序列化,将 Java 对象转为字节数据持久化到磁盘 / 网络。
0.3.2 字符流实现类
字符输入流
  • FileReader:文件字符输入流,基础字符流,用于读取文本文件,默认使用系统编码,本质是InputStreamReader的子类,封装了文件字节流的字符转换逻辑。
  • BufferedReader:缓冲字符输入流,内置字符缓冲区,提升文本读取效率,额外提供readLine()方法,支持按行读取文本,是文本读取最常用的类。
  • InputStreamReader:字节→字符转换流,是字节流和字符流的桥梁,支持手动指定编码格式,解决非系统默认编码文本的乱码问题。
字符输出流
  • FileWriter:文件字符输出流,基础字符输出流,用于向文本文件写入字符数据,默认使用系统编码,是OutputStreamWriter的子类。
  • BufferedWriter:缓冲字符输出流,内置字符缓冲区,提升文本写入效率,提供newLine()方法写入跨平台兼容的换行符。
  • OutputStreamWriter:字符→字节转换流,字符流和字节流的桥梁,支持手动指定编码,是解决文本编码乱码的核心类。
  • PrintWriter:打印字符流,对标PrintStream,提供print/println等便捷打印方法,支持自动刷新,可包装输出流 / Writer,是文本输出场景的常用类。

1. 字节流体系(以 byte 为单位,万

能流)

1.1 字节输入流(InputStream 分支)

1.1.1 顶级抽象类:InputStream
  • 定位:所有字节输入流的父类,定义字节读取的通用规范,无法直接实例化
  • 核心方法(区分参数 / 返回类型):
    方法签名 方法作用 参数类型 返回类型
    abstract int read() 读取单个字节 int(返回字节值,范围 0-255;读到末尾返回 -1)
    int read(byte b[]) 读取字节到数组 byte[](目标数组) int(实际读取的字节数;读到末尾返回 -1)
    int read(byte b[], int off, int len) 读取字节到数组指定区间 byte[](目标数组)、int(起始偏移)、int(读取长度) int(实际读取的字节数;读到末尾返回 -1)
    void close() 关闭流释放资源 void

1.1.2 基础节点流:FileInputStream
  • 定位:直接操作文件的字节输入流,从本地文件读取原始字节数据,最简单的文件读取流
  • 继承链java.lang.Objectjava.io.InputStreamjava.io.FileInputStream
  • 核心变量(区分类型):
    • private FileDescriptor fdFileDescriptor 类型:文件描述符,关联操作系统文件)
    • private String pathString 类型:文件路径)
  • 核心构造方法
    构造方法签名 参数类型 作用
    FileInputStream(String name) String(文件路径字符串) 绑定路径对应的文件
    FileInputStream(File file) File(文件对象) 绑定 File 对象对应的文件
  • 示例代码
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample {
    public static void main(String[] args) {
        File srcFile = new File("src.txt");
        
        // try-with-resources:自动关闭流,无需手动 finally
        try (FileInputStream fis = new FileInputStream(srcFile)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.1.3 缓冲处理流:BufferedInputStream
  • 定位:基于装饰器模式的缓冲流,不直接操作文件,而是包装其他字节输入流,通过内置缓冲区减少磁盘 IO 次数,大幅提升读取效率
  • 继承链java.lang.Objectjava.io.InputStreamjava.io.FilterInputStreamjava.io.BufferedInputStream
  • 核心变量(区分类型):
    • protected byte buf[]byte[] 类型:内置缓冲区数组,默认大小 8192 字节)
    • protected int countint 类型:缓冲区中有效字节总数)
    • protected int posint 类型:当前缓冲区读取位置)
  • 核心构造方法
    构造方法签名 参数类型 作用
    BufferedInputStream(InputStream in) InputStream(被包装的基础流) 用默认 8KB 缓冲区包装输入流
    BufferedInputStream(InputStream in, int size) InputStreamint(缓冲区大小) 用指定大小缓冲区包装输入流
  • 核心增强方法
    方法签名 作用 返回类型
    void mark(int readlimit) 标记当前读取位置 void
    void reset() 重置到 mark 标记的位置 void
  • 示例代码(包装 FileInputStream 提升效率):
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamExample {
    public static void main(String[] args) {
        // try() 里定义流,自动关闭
        try (FileInputStream fis = new FileInputStream("src.txt");
             BufferedInputStream bis = new BufferedInputStream(fis)) {
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.1.4 数据处理流:DataInputStream
  • 定位:专门用于读取 Java 基本数据类型intdoubleboolean 等)的流,保证数据读写的 “平台无关性”(不同操作系统读取结果一致)。
  • 继承链java.lang.Objectjava.io.InputStreamjava.io.FilterInputStreamjava.io.DataInputStream
  • 核心接口实现java.io.DataInput(定义基本类型读取规范)
  • 核心方法(按类型读取):
    方法签名 读取类型 返回类型
    boolean readBoolean() 布尔值 boolean
    byte readByte() 字节 byte
    int readInt() 整数 int
    double readDouble() 双精度浮点数 double
    String readUTF() UTF-8 编码字符串 String
  • 示例代码(需配合 DataOutputStream 写入后读取):
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class DataInputStreamExample {
    public static void main(String[] args) {
        // 先运行 DataOutputStreamExample 写入数据,再运行此代码读取
        try (DataInputStream dis = new DataInputStream(new FileInputStream("data.dat"))) {
            // 按写入顺序读取基本类型
            int num = dis.readInt();          // 读取 int
            double price = dis.readDouble();  // 读取 double
            boolean flag = dis.readBoolean(); // 读取 boolean
            String name = dis.readUTF();      // 读取 String
            
            System.out.println("读取到的 int: " + num);
            System.out.println("读取到的 double: " + price);
            System.out.println("读取到的 boolean: " + flag);
            System.out.println("读取到的 String: " + name);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.1.5 对象处理流:ObjectInputStream
  • 定位:用于对象反序列化的流,将之前通过 ObjectOutputStream 持久化到磁盘的 “字节序列” 还原为 Java 对象。
  • 继承链java.lang.Objectjava.io.InputStreamjava.io.ObjectInputStream
  • 核心接口实现java.io.ObjectInputjava.io.ObjectStreamConstants
  • 核心方法
    方法签名 作用 返回类型
    final Object readObject() 读取并反序列化对象 Object(需强转为目标类型)
    void close() 关闭流 void
  • 前提要求:被序列化的类必须实现 java.io.Serializable 接口(标记接口,无抽象方法)。
  • 示例代码(先定义可序列化的类,再反序列化):
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

// 1. 定义可序列化的类(必须实现 Serializable 接口)
class User implements Serializable {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}

public class ObjectInputStreamExample {
    public static void main(String[] args) {
        // 先运行 ObjectOutputStreamExample 写入对象,再运行此代码读取
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
            // 2. 反序列化对象(返回 Object,需强转为 User)
            User user = (User) ois.readObject();
            System.out.println("反序列化得到的对象: " + user);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

1.2 字节输出流(OutputStream 分支)

1.2.1 顶级抽象类:OutputStream
  • 定位:所有字节输出流的父类,定义字节写入的通用规范,无法直接实例化
  • 核心方法(区分参数 / 返回类型):
    方法签名 方法作用 参数类型 返回类型
    abstract void write(int b) 写入单个字节 int(字节值,低 8 位有效) void
    void write(byte b[]) 写入整个字节数组 byte[](源数组) void
    void write(byte b[], int off, int len) 写入数组指定区间 byte[](源数组)、int(起始偏移)、int(写入长度) void
    void flush() 刷新缓冲区,将数据写入目标 void
    void close() 关闭流释放资源 void

1.2.2 基础节点流:FileOutputStream
  • 定位:直接操作文件的字节输出流,向本地文件写入原始字节数据,最简单的文件写入流
  • 继承链java.lang.Objectjava.io.OutputStreamjava.io.FileOutputStream
  • 核心变量(区分类型):
    • private FileDescriptor fdFileDescriptor 类型:文件描述符)
    • private boolean appendboolean 类型:是否追加写入,true 为追加,false 为覆盖)
  • 核心构造方法
    构造方法签名 参数类型 作用
    FileOutputStream(String name) String(文件路径) 覆盖模式绑定文件
    FileOutputStream(String name, boolean append) Stringboolean(是否追加) 按指定模式绑定文件
    FileOutputStream(File file) File(文件对象) 覆盖模式绑定 File 对象
  • 示例代码(覆盖写入 + 追加写入):
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamExample {
    public static void main(String[] args) {
        File destFile = new File("dest.txt");
        
        // 自动关闭流,无需 finally
        try (FileOutputStream fos = new FileOutputStream(destFile, true)) {
            fos.write(97);
            String content = "Hello, Java IO!";
            byte[] data = content.getBytes();
            fos.write(data);
            fos.write(data, 0, 5);
            System.out.println("写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2.3 缓冲处理流:BufferedOutputStream
  • 定位:字节输出缓冲流,包装其他字节输出流,通过内置缓冲区减少磁盘 IO 次数,提升写入效率(数据先写缓冲区,满了或 flush() 时才写入磁盘)。
  • 继承链java.lang.Objectjava.io.OutputStreamjava.io.FilterOutputStreamjava.io.BeredOutputStream
  • 核心变量(区分类型):
    • protected byte buf[]byte[] 类型:内置缓冲区,默认 8192 字节)
    • protected int countint 类型:缓冲区中已写入的字节数)
  • 核心构造方法
    构造方法签名 参数类型 作用
    BufferedOutputStream(OutputStream out) OutputStream(被包装的基础流) 用默认 8KB 缓冲区包装输出流
    BufferedOutputStream(OutputStream out, int size) OutputStreamint(缓冲区大小) 用指定大小缓冲区包装输出流
  • 示例代码(包装 FileOutputStream 提升效率):
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamExample {
    public static void main(String[] args) {
        try (FileOutputStream fos = new FileOutputStream("buffered_dest.txt");
             BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            
            String content = "BufferedOutputStream 效率更高!";
            bos.write(content.getBytes());
            // close 自动 flush,短代码可省略手动 flush
            System.out.println("缓冲写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2.4 打印处理流:PrintStream
  • 定位:最 “常用” 的字节打印流,提供便捷的打印方法print()println()printf()),支持打印所有数据类型,不会抛出 IOException(内部捕获异常,通过 checkError() 检查)。
  • 经典应用System.out 就是 PrintStream 类型(标准输出流,打印到控制台)。
  • 继承链java.lang.Objectjava.io.OutputStreamjava.io.FilterOutputStreamjava.io.PrintStream
  • 核心方法(按打印类型):
    方法签名 打印类型 返回类型
    void print(String s) 字符串(不换行) void
    void println(String x) 字符串(换行) void
    void println(int x) 整数(换行) void
    PrintStream printf(String format, Object... args) 格式化字符串 PrintStream(返回自身,支持链式调用)
  • 示例代码(打印到文件 + 格式化打印):
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamExample {
    public static void main(String[] args) {
        // 1. 包装 FileOutputStream 为 PrintStream
        try (PrintStream ps = new PrintStream(new FileOutputStream("print.txt"))) {
            // 2. 便捷打印各类数据
            ps.print("Hello, ");       // 不换行打印字符串
            ps.println("PrintStream!"); // 换行打印字符串
            ps.println(123);            // 打印整数
            ps.println(3.14);           // 打印浮点数
            ps.println(true);           // 打印布尔值
            
            // 3. 格式化打印(类似 C 语言 printf)
            String name = "张三";
            int age = 25;
            ps.printf("姓名: %s, 年龄: %d\n", name, age);
            
            System.out.println("打印完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2.5 数据处理流:DataOutputStream
  • 定位:与 DataInputStream 配对,专门用于写入 Java 基本数据类型的流,保证数据写入的 “平台无关性”。
  • 继承链java.lang.Objectjava.io.OutputStreamjava.io.FilterOutputStreamjava.io.DataOutputStream
  • 核心接口实现java.io.DataOutput(定义基本类型写入规范)
  • 核心方法(按类型写入):
    方法签名 写入类型 返回类型
    void writeBoolean(boolean v) 布尔值 void
    void writeByte(int v) 字节 void
    void writeInt(int v) 整数 void
    void writeDouble(double v) 双精度浮点数 void
    void writeUTF(String str) UTF-8 编码字符串 void
  • 示例代码(写入基本类型,供 DataInputStream 读取):
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataOutputStreamExample {
    public static void main(String[] args) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.dat"))) {
            // 按顺序写入基本类型
            dos.writeInt(100);          // 写入 int
            dos.writeDouble(99.99);     // 写入 double
            dos.writeBoolean(true);      // 写入 boolean
            dos.writeUTF("Java IO");     // 写入 String
            
            System.out.println("基本类型数据写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2.6 对象处理流:ObjectOutputStream
  • 定位:用于对象序列化的流,将 Java 对象转为 “字节序列” 持久化到磁盘(或网络传输),是 Java 轻量级持久化的常用方式。
  • 继承链java.lang.Objectjava.io.OutputStreamjava.io.ObjectOutputStream
  • 核心接口实现java.io.ObjectOutputjava.io.ObjectStreamConstants
  • 核心方法
    方法签名 作用 返回类型
    final void writeObject(Object obj) 序列化对象 void
    void close() 关闭流 void
  • 示例代码(序列化 User 对象,供 ObjectInputStream 读取):
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

// 复用之前定义的 User 类(必须实现 Serializable)
public class ObjectOutputStreamExample {
    public static void main(String[] args) {
        // 1. 创建要序列化的对象
        User user = new User("李四", 30);
        
        // 2. 序列化对象到文件
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
            oos.writeObject(user);
            System.out.println("对象序列化完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 字符流体系(以 char 为单位,专门处理文本)

2.1 字符输入流(Reader 分支)

2.1.1 顶级抽象类:Reader
  • 定位:所有字符输入流的父类,定义字符读取的通用规范,无法直接实例化
  • 核心方法(区分参数 / 返回类型):
    方法签名 方法作用 参数类型 返回类型
    int read() 读取单个字符 int(返回字符值,范围 0-65535;读到末尾返回 -1)
    int read(char cbuf[]) 读取字符到数组 char[](目标数组) int(实际读取的字符数;读到末尾返回 -1)
    abstract int read(char cbuf[], int off, int len) 读取字符到数组指定区间 char[]int(起始偏移)、int(读取长度) int(实际读取的字符数;读到末尾返回 -1)
    void close() 关闭流释放资源 void

2.1.2 转换流:InputStreamReader
  • 定位字节流 → 字符流的桥梁,将字节输入流按指定编码(如 UTF-8、GBK)转为字符输入流,解决文本乱码的核心类
  • 继承链java.lang.Objectjava.io.Readerjava.io.InputStreamReader
  • 核心变量(区分类型):
    • private final StreamDecoder sdStreamDecoder 类型:流解码器,负责字节→字符的编码转换)
  • 核心构造方法
    构造方法签名 参数类型 作用
    InputStreamReader(InputStream in) InputStream(字节输入流) 用系统默认编码转换字节流
    InputStreamReader(InputStream in, String charsetName) InputStreamString(编码名称) 用指定编码转换字节流
  • 示例代码(指定 UTF-8 编码读取文本,避免乱码):
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("utf8_text.txt");
             InputStreamReader isr = new InputStreamReader(fis, "UTF-8")) {
            
            char[] buffer = new char[1024];
            int len;
            while ((len = isr.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.1.3 基础节点流:FileReader
  • 定位:直接操作文件的字符输入流,本质是 InputStreamReader 的子类(默认用系统编码转换字节流),是读取文本文件的 “简易版” 流。
  • 继承链java.lang.Objectjava.io.Readerjava.io.InputStreamReaderjava.io.FileReader
  • 核心构造方法
    构造方法签名 参数类型 作用
    FileReader(String fileName) String(文件路径) 绑定路径对应的文本文件
    FileReader(File file) File(文件对象) 绑定 File 对象对应的文本文件
  • 注意FileReader 无法指定编码,只能用系统默认编码,非 UTF-8 编码文本可能乱码(此时建议用 InputStreamReader)。
  • 示例代码(简易读取文本文件):
import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {
    public static void main(String[] args) {
        // 直接用 FileReader 读取(系统默认编码)
        try (FileReader fr = new FileReader("src.txt")) {
            char[] buffer = new char[1024];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.1.4 缓冲处理流:BufferedReader
  • 定位:字符输入缓冲流,包装其他字符输入流,通过内置缓冲区提升文本读取效率,额外提供 readLine() 方法按行读取文本(文本读取最常用的流)。
  • 继承链java.lang.Objectjava.io.Readerjava.io.BufferedReader
  • 核心变量(区分类型):
    • private char cb[]char[] 类型:内置字符缓冲区,默认 8192 字符)
    • private int nCharsint 类型:缓冲区中有效字符总数)
    • private int nextCharint 类型:当前缓冲区读取位置)
  • 核心构造方法
    构造方法签名 参数类型 作用
    BufferedReader(Reader in) Reader(被包装的字符流) 用默认缓冲区包装字符流
    BufferedReader(Reader in, int sz) Readerint(缓冲区大小) 用指定大小缓冲区包装字符流
  • 核心增强方法
    方法签名 作用 返回类型
    String readLine() 读取一行文本(不包含换行符) String(读到末尾返回 null
  • 示例代码(按行读取文本,最常用的文本读取方式):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {
    public static void main(String[] args) {
        // 1. 包装 FileReader 为 BufferedReader
        try (BufferedReader br = new BufferedReader(new FileReader("src.txt"))) {
            String line; // 变量类型:String,存储每行文本
            // 2. 按行读取:readLine() 返回一行文本,读到末尾返回 null
            while ((line = br.readLine()) != null) {
                System.out.println("读取到一行: " + line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2 字符输出流(Writer 分支)

2.2.1 顶级抽象类:Writer
  • 定位:所有字符输出流的父类,定义字符写入的通用规范,无法直接实例化
  • 核心方法(区分参数 / 返回类型):
    方法签名 方法作用 参数类型 返回类型
    void write(int c) 写入单个字符 int(字符值,低 16 位有效) void
    void write(char cbuf[]) 写入整个字符数组 char[](源数组) void
    abstract void write(char cbuf[], int off, int len) 写入数组指定区间 char[]int(起始偏移)、int(写入长度) void
    void write(String str) 写入整个字符串 String(源字符串) void
    void flush() 刷新缓冲区 void
    void close() 关闭流释放资源 void

2.2.2 转换流:OutputStreamWriter
  • 定位字符流 → 字节流的桥梁,将字符输出流按指定编码转为字节输出流,解决文本写入乱码的核心类
  • 继承链java.lang.Objectjava.io.Writerjava.io.OutputStreamWriter
  • 核心变量(区分类型):
    • private final StreamEncoder seStreamEncoder 类型:流编码器,负责字符→字节的编码转换)
  • 核心构造方法
    构造方法签名 参数类型 作用
    OutputStreamWriter(OutputStream out) OutputStream(字节输出流) 用系统默认编码转换字符流
    OutputStreamWriter(OutputStream out, String charsetName) OutputStreamString(编码名称) 用指定编码转换字符流
  • 示例代码(指定 UTF-8 编码写入文本,避免乱码):
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterExample {
    public static void main(String[] args) {
        try (FileOutputStream fos = new FileOutputStream("utf8_dest.txt");
             OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")) {
            
            osw.write("你好,Java IO!");
            osw.write("\n");
            osw.write("指定 UTF-8 编码写入。");
            // 无需手动 flush、close,自动完成
            System.out.println("指定编码写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.3 基础节点流:FileWriter
  • 定位:直接操作文件的字符输出流,本质是 OutputStreamWriter 的子类(默认用系统编码转换字节流),是写入文本文件的 “简易版” 流。
  • 继承链java.lang.Objectjava.io.Writerjava.io.OutputStreamWriterjava.io.FileWriter
  • 核心构造方法
    构造方法签名 参数类型 作用
    FileWriter(String fileName) String(文件路径) 覆盖模式绑定文本文件
    FileWriter(String fileName, boolean append) Stringboolean(是否追加) 按指定模式绑定文本文件
    FileWriter(File file) File(文件对象) 覆盖模式绑定 File 对象
  • 注意FileWriter 无法指定编码,非 UTF-8 编码文本可能乱码(此时建议用 OutputStreamWriter)。
  • 示例代码(简易写入文本文件):
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterExample {
    public static void main(String[] args) {
        // 直接用 FileWriter 写入(append=true 表示追加)
        try (FileWriter fw = new FileWriter("dest.txt", true)) {
            fw.write("FileWriter 简易写入!\n");
            fw.write("这是追加的内容。");
            System.out.println("简易写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.4 缓冲处理流:BufferedWriter
  • 定位:字符输出缓冲流,包装其他字符输出流,通过内置缓冲区提升文本写入效率,额外提供 newLine() 方法写入跨平台兼容的换行符(不同操作系统换行符不同,newLine() 自动适配)。
  • 继承链java.lang.Objectjava.io.Writerjava.io.BufferedWriter
  • 核心变量(区分类型):
    • private char cb[]char[] 类型:内置字符缓冲区,默认 8192 字符)
    • private int nCharsint 类型:缓冲区大小)
    • private int nextCharint 类型:当前缓冲区写入位置)
  • 核心构造方法
    构造方法签名 参数类型 作用
    BufferedWriter(Writer out) Writer(被包装的字符流) 用默认缓冲区包装字符流
    BufferedWriter(Writer out, int sz) Writerint(缓冲区大小) 用指定大小缓冲区包装字符流
  • 核心增强方法
    方法签名 作用 返回类型
    void newLine() 写入跨平台换行符 void
  • 示例代码(缓冲写入 + 跨平台换行):
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterExample {
    public static void main(String[] args) {
        // 1. 包装 FileWriter 为 BufferedWriter
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("buffered_text.txt"))) {
            // 2. 写入文本
            bw.write("BufferedWriter 缓冲写入");
            bw.newLine(); // 跨平台换行(Windows: \r\n, Linux: \n)
            bw.write("效率更高,且换行符兼容!");
            
            bw.flush();
            System.out.println("缓冲写入完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.5 打印处理流:PrintWriter
  • 定位:字符打印流,功能与 PrintStream 类似,提供便捷的打印方法print()println()printf()),支持打印所有数据类型,更适合文本输出场景(可自动刷新)。
  • 继承链java.lang.Objectjava.io.Writerjava.io.PrintWriter
  • 核心构造方法
    构造方法签名 参数类型 作用
    PrintWriter(Writer out) Writer(字符输出流) 包装字符流,不自动刷新
    PrintWriter(Writer out, boolean autoFlush) Writerboolean(是否自动刷新) 包装字符流,指定是否自动刷新
    PrintWriter(OutputStream out) OutputStream(字节输出流) 直接包装字节流(内部自动转为字符流)
  • 核心方法(与 PrintStream 一致):
    方法签名 打印类型 返回类型
    void print(String s) 字符串(不换行) void
    void println(String x) 字符串(换行) void
    PrintWriter printf(String format, Object... args) 格式化字符串 PrintWriter(链式调用)
  • 示例代码(自动刷新 + 格式化打印):
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterExample {
    public static void main(String[] args) {
        // 1. 包装 FileWriter,autoFlush=true 表示 println/printf 后自动刷新
        try (PrintWriter pw = new PrintWriter(new FileWriter("print_writer.txt"), true)) {
            // 2. 便捷打印
            pw.println("PrintWriter 字符打印流");
            pw.println(12345);
            
            // 3. 格式化打印
            double price = 19.99;
            int count = 3;
            pw.printf("单价: %.2f, 数量: %d, 总价: %.2f\n", price, count, price * count);
            
            System.out.println("PrintWriter 打印完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. IO 流体系总结与选型建议

3.1 类的层级关系全景

流类型 顶级抽象类 基础节点流 转换流 缓冲处理流 数据 / 对象 / 打印处理流
字节输入流 InputStream FileInputStream - BufferedInputStream DataInputStreamObjectInputStream
字节输出流 OutputStream FileOutputStream - BufferedOutputStream DataOutputStreamObjectOutputStreamPrintStream
字符输入流 Reader FileReader InputStreamReader BufferedReader -
字符输出流 Writer FileWriter OutputStreamWriter BufferedWriter PrintWriter

3.2 选型原则(按场景选择)

  1. 二进制文件(图片、视频、压缩包等):必须用字节流FileInputStream/FileOutputStream + 缓冲流)。
  2. 纯文本文件(txt、java、html 等):优先用字符流FileReader/FileWriterBufferedReader/BufferedWriter)。
  3. 非 UTF-8 编码文本必须用转换流InputStreamReader/OutputStreamWriter 指定编码)。
  4. 大文件读写必须加缓冲流BufferedXxx),减少 IO 次数,提升效率。
  5. 基本数据类型读写:用 DataInputStream/DataOutputStream
  6. 对象持久化:用 ObjectInputStream/ObjectOutputStream(类需实现 Serializable)。
  7. 便捷打印文本:用 PrintStream(字节)或 PrintWriter(字符,推荐)。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐