flush()的作用是立即将缓冲区中未写出的字符数据强制写入底层目标,避免因缓冲导致数据延迟可见;需手动调用以确保日志、网络消息等及时生效,常见需关注的流包括bufferedwriter和非自动刷新的printwriter。

Java 字符流(如 OutputStreamWriter、PrintWriter、BufferedWriter)内部通常自带缓冲区,flush() 方法的作用就是**立即将缓冲区中尚未写出的字符数据强制写入底层目标(如文件、网络流或控制台)**,而不是等待缓冲区满或流关闭时才写入。
为什么需要手动调用 flush()?
缓冲区的存在是为了提升 I/O 效率,但也会带来“延迟可见性”问题:你调用了 write() 或 println(),数据可能还卡在内存缓冲区里,并未真正落到目标位置。比如:
- 向文件写日志后立即想查看内容,不
flush()可能看不到最新行; - 通过 socket 发送文本消息,对方收不到,因为数据还在发送端缓冲区;
- 调试时用
System.out.println()打印,但程序异常退出没输出——因为System.out是带缓冲的PrintStream,异常中断前未自动刷出。
哪些字符流需要关注 flush()?
以下常见类内部维护了字符缓冲区,flush() 对它们有效且必要:
-
BufferedWriter:典型缓冲字符输出流,必须flush()才能确保内容写入底层Writer; -
PrintWriter(构造时传入autoFlush=false或默认构造):默认不自动 flush,需手动调用; -
OutputStreamWriter:本身不缓存,但若包装在BufferedWriter中,则由外层负责 flush; -
StringWriter不需要 flush —— 它写入内存StringBuilder,无 I/O 延迟。
flush() 的正确使用时机
flush() 不会关闭流,可多次调用,安全无副作用。建议在这些场景显式调用:
- 一次逻辑操作完成,希望结果立即生效(如写完一行配置就刷出);
- 在
try-with-resources外提前确保数据落盘(虽然资源关闭会自动 flush,但关闭前可能已出错); - 与实时性要求高的外部系统交互(如命令行工具响应、串口通信);
- 捕获异常后,在清理前尝试刷出最后日志(即使失败也尽力保留线索)。
一个典型例子
下面代码演示了不 flush 和 flush 的区别:
BufferedWriter bw = new BufferedWriter(new FileWriter("log.txt"));bw.write("Start processing...");// 此时内容仍在内存缓冲区bw.flush(); // ← 关键:立刻写入文件bw.write("Done.");bw.close(); // close 内部也会 flush,但主动 flush 更可控
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











