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

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

示例:使用 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();
}
}
}

🔹 为什么 BufferedReaderFileReader 更高效?

  • 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 效率 方面,缓冲流是 优先选择。🚀