JAVA IO流:从基础原理到实战应用

4 阅读4分钟

Java IO 流:从基础原理到实战应用(超完整总结)

下面用清晰、系统、面试+开发都能用的方式,把 Java IO 从头到尾讲透,包括分类、原理、字节流/字符流、缓冲流、转换流、打印流、对象流、文件操作、NIO 简介


一、先搞懂:什么是 IO?

IO = Input / Output

  • Input:从外部(文件、网络、键盘)读入程序内存
  • Output:从程序内存写出到外部(文件、网络、控制台)

Java IO 的核心设计思想:

基于流(Stream)的设计 数据像水流一样,按顺序传输,不能回头。


二、IO 流的四大核心分类

1. 按数据方向分

  • 输入流(InputStream / Reader) :读数据
  • 输出流(OutputStream / Writer) :写数据

2. 按数据单位分

  • 字节流(Byte Stream) :以 ​​byte​​ 为单位,万能流
  • 顶层父类:​​InputStream​​、​​OutputStream​
  • 字符流(Char Stream) :以 ​​char​​ 为单位,专门处理文本
  • 顶层父类:​​Reader​​、​​Writer​

3. 按功能分

  • 节点流(低级流) :直接连接数据源(文件、数组等)
  • 处理流(高级流/包装流) :对节点流包装,增强功能(缓冲、对象序列化等)

三、字节流(万能流)

1. 核心类

  • 文件输入:​​FileInputStream​
  • 文件输出:​​FileOutputStream​

2. 适用场景

  • 图片、音频、视频、压缩包等二进制文件
  • 任何文件都能用(文本也可以,但容易乱码)

3. 基础用法(复制文件标准模板)

try (
    FileInputStream in = new FileInputStream("a.jpg");
    FileOutputStream out = new FileOutputStream("b.jpg");
) {
    byte[] buf = new byte[1024 * 8];
    int len;
    while ((len = in.read(buf)) != -1) {
        out.write(buf, 0, len);
    }
} catch (IOException e) {
    e.printStackTrace();
}

读到 ​​-1​​ 表示文件结束。


四、字符流(专门处理文本)

1. 核心类

  • 文件读取:​​FileReader​
  • 文件写入:​​FileWriter​

2. 特点

  • 字符为单位,自动处理编码
  • 只适合纯文本文件

3. 基础用法

try (
    FileReader fr = new FileReader("a.txt");
    FileWriter fw = new FileWriter("b.txt");
) {
    char[] cbuf = new char[1024];
    int len;
    while ((len = fr.read(cbuf)) != -1) {
        fw.write(cbuf, 0, len);
    }
} catch (IOException e) {
    e.printStackTrace();
}

五、缓冲流(提高性能,开发必用)

对普通流包装,减少磁盘 IO,速度大幅提升。

1. 字节缓冲流

  • ​BufferedInputStream​
  • ​BufferedOutputStream​

2. 字符缓冲流

  • ​BufferedReader​​:独有 readLine() 读一行
  • ​BufferedWriter​​:独有 newLine() 换行

3. 字符缓冲流实战(按行读写)

try (
    BufferedReader br = new BufferedReader(new FileReader("in.txt"));
    BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
) {
    String line;
    while ((line = br.readLine()) != null) {
        bw.write(line);
        bw.newLine();
    }
} catch (IOException e) {
    e.printStackTrace();
}

六、转换流(解决编码乱码神器)

核心类

  • ​InputStreamReader​​:字节流 → 字符流
  • ​OutputStreamWriter​​:字符流 → 字节流

作用

指定编码读写(UTF-8、GBK 等),彻底解决乱码。

// 用 GBK 读取
InputStreamReader isr = new InputStreamReader(
    new FileInputStream("gbk.txt"), "GBK");

// 用 UTF-8 写出
OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream("utf8.txt"), "UTF-8");

七、打印流(方便输出)

核心类

  • ​PrintStream​​(字节)
  • ​PrintWriter​​(字符)

特点:

  • 不会抛 IO 异常
  • 有 ​​print()​​ / ​​println()​​ 方法
  • 常用:​​System.out​​ 就是 ​​PrintStream​
PrintWriter pw = new PrintWriter("log.txt");
pw.println("Hello");
pw.println(123);
pw.close();

八、对象流(序列化与反序列化)

作用

把 Java 对象写入文件/网络,或从文件读取对象。

核心类

  • ​ObjectOutputStream​​:序列化(写对象)
  • ​ObjectInputStream​​:反序列化(读对象)

要求

类必须实现 ​​Serializable​​ 接口。

// 写对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
    User user = new User("张三", 20);
    oos.writeObject(user);
}

// 读对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
    User user = (User) ois.readObject();
}

九、标准 IO 实战案例

1. 复制任意文件(字节缓冲流)

try (
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("src.mp4"));
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("dest.mp4"));
) {
    byte[] buf = new byte[8192];
    int len;
    while ((len = in.read(buf)) != -1) {
        out.write(buf, 0, len);
    }
}

2. 读取文本并统计行数

int count = 0;
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
    while (br.readLine() != null) count++;
}
System.out.println("总行数:" + count);

3. 按编码复制文本(解决乱码)

try (
    BufferedReader br = new BufferedReader(
        new InputStreamReader(new FileInputStream("a.txt"), "GBK"));
    BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(new FileOutputStream("b.txt"), "UTF-8"));
) {
    String line;
    while ((line = br.readLine()) != null) {
        bw.write(line);
        bw.newLine();
    }
}

十、IO 流体系总表(记忆神器)

分类输入流输出流作用
字节节点流FileInputStreamFileOutputStream读写任意文件
字符节点流FileReaderFileWriter读写文本
字节缓冲流BufferedInputStreamBufferedOutputStream提高字节流速度
字符缓冲流BufferedReaderBufferedWriter按行读写,高性能文本
转换流InputStreamReaderOutputStreamWriter编码转换、解决乱码
对象流ObjectInputStreamObjectOutputStream对象序列化
打印流/PrintStream/PrintWriter方便打印输出

十一、IO 关闭原则(非常重要)

  1. 从外到内关闭
  2. JDK7+ 推荐 try-with-resources 实现 ​​AutoCloseable​​ 接口的流会自动关闭,不用手动 ​​close()​

十二、BIO、NIO、AIO 简单区别

  • BIO(传统 IO) :阻塞流,一个连接一个线程
  • NIO(Java 4+) :非阻塞、面向缓冲区、多路复用
  • AIO(Java 7+) :异步非阻塞,基于事件和回调

日常文件读写用 BIO 足够;高并发网络编程用 NIO


十三、面试高频考点

  1. 字节流和字符流区别
  2. flush() 和 close() 的关系
  3. 缓冲流为什么快
  4. 序列化注意事项
  5. try-with-resources 原理
  6. 如何解决 IO 乱码

如果你需要,我可以继续给你:

  • 一套 Java IO 常考面试题+标准答案
  • 一份 IO 流实战作业(含答案)
  • 或者 从 BIO 到 NIO 的完整进阶教程

你想要哪个?