Java 缓冲流(Buffered Stream)详解

在 Java IO 中,缓冲流(Buffered Stream) 是对基本 IO 流的 增强,它提供 缓冲区 来减少直接与硬盘或网络交互的次数,从而提高 读写效率。

Java 提供了 字节缓冲流 和 字符缓冲流 两大类,用于字节流(InputStream/OutputStream)和字符流(Reader/Writer)的优化。


✅ 1. 缓冲流的作用

  • 减少 IO 操作次数:普通流每次 read() 或 write() 操作都会进行 一次磁盘 IO,而缓冲流会 一次性读取/写入多个字节或字符,提高性能。
  • 提高读写效率:缓存数据到 内存缓冲区,减少对底层物理设备的直接访问,提高程序性能。
  • 提供更方便的方法:如 BufferedReader.readLine() 可直接 读取一整行,比 FileReader.read() 逐个字符读取更高效。

✅ 2. 缓冲流的分类

缓冲流分为 字节缓冲流 和 字符缓冲流:

流类型 对应的普通流 缓冲流
字节输入流 FileInputStream BufferedInputStream
字节输出流 FileOutputStream BufferedOutputStream
字符输入流 FileReader BufferedReader
字符输出流 FileWriter BufferedWriter

✅ 3. 字节缓冲流(BufferedInputStream / BufferedOutputStream)

📌 3.1 字节缓冲输入流 BufferedInputStream

用于 加快字节读取速度,它会 一次性读取较大块数据到缓冲区,然后从缓冲区按需提供数据,而不是每次都直接访问文件。

示例:使用 BufferedInputStream 读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;

public class BufferedInputStreamExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.txt"))) {
int data;
while ((data = bis.read()) != -1) {
System.out.print((char) data); // 逐字节读取
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 和 FileInputStream 的区别:

  • FileInputStream.read() 每次 读取一个字节,如果文件很大,会频繁访问磁盘,效率低。
  • BufferedInputStream 一次性读取多个字节,减少磁盘访问次数,提高效率。

📌 3.2 字节缓冲输出流 BufferedOutputStream

用于 加快字节写入速度,它会 先写入缓冲区,当缓冲区满了或 flush() 被调用时,才会将数据写入目标文件。

示例:使用 BufferedOutputStream 写入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.io.*;

public class BufferedOutputStreamExample {
public static void main(String[] args) {
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
String data = "Hello, Java IO!";
bos.write(data.getBytes()); // 先写入缓冲区
bos.flush(); // 强制刷新缓冲区,确保数据写入文件
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 重点:

  • flush() 方法 强制写出缓冲区数据,确保数据及时保存到文件。
  • 若不调用 flush() 或 close(),可能导致部分数据未写入文件。

✅ 4. 字符缓冲流(BufferedReader / BufferedWriter)

字符缓冲流 用于 文本文件 的高效读写,它基于 Reader / Writer,支持 整行读取、写入。


📌 4.1 字符缓冲输入流 BufferedReader

相比 FileReader,BufferedReader 提供了 按行读取 的方法,适用于读取 文本文件。

示例:使用 BufferedReader 按行读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;

public class BufferedReaderExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) { // 按行读取,提高效率
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 为什么 BufferedReader 比 FileReader 更高效?

  • BufferedReader.readLine() 一次性读取一整行,避免多次调用 read(),减少 IO 操作。
  • 适用于读取大文本文件,如日志分析、配置文件解析等。

📌 4.2 字符缓冲输出流 BufferedWriter

用于 高效写入文本文件,支持 写入换行(newLine() 方法)。

示例:使用 BufferedWriter 写入文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;

public class BufferedWriterExample {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
bw.write("Hello, Java IO!");
bw.newLine(); // 写入换行符
bw.write("This is a new line.");
bw.flush(); // 刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
}
}
}

🔹 重点:

  • newLine() 写入换行符,兼容不同操作系统(Windows: \r\n,Linux: \n)。
  • flush() 强制将数据从缓冲区写入文件,保证数据不会丢失。

✅ 5. 缓冲流 vs 普通流 性能对比

普通流 vs 缓冲流

操作 普通流(FileInputStream) 缓冲流(BufferedInputStream)
读取方式 逐字节读取,每次访问磁盘 先读入缓冲区,再批量返回
写入方式 逐字节写入,每次写入磁盘 先写入缓冲区,满了再写入磁盘
适用场景 小文件、零散数据读写 大文件、高频读写
性能 低效 高效

如果 文件较大 或 读写操作频繁,建议使用缓冲流 来提升性能。


✅ 6. 总结

流类型 用于 适用场景 常用方法
BufferedInputStream 字节输入(加快读取) 读取二进制文件(图片、视频) read()
BufferedOutputStream 字节输出(加快写入) 写入二进制文件 write()、flush()
BufferedReader 字符输入(按行读取) 读取文本文件(日志、CSV) readLine()
BufferedWriter 字符输出(高效写入) 写入文本文件 write()、newLine()

💡 推荐使用缓冲流! 在 处理大文件、提高 IO 效率 方面,缓冲流是 优先选择。🚀