flush()不能强制落盘,仅将Java缓冲区数据刷新至操作系统内核缓存;真正落盘需在flush()后调用getChannel().force(true)或FileDescriptor.sync()。

Java 中的 flush() 方法并不能强制将数据写入磁盘,它只是将缓冲区中的数据**刷新到操作系统内核的缓冲区**(即写出到文件系统缓存),而非真正落盘。要确保数据物理写入磁盘,必须配合 getChannel().force(true) 或 FileDescriptor.sync() 使用。
flush() 的真实作用
flush() 主要用于清空 Java 层的缓冲区(如 BufferedOutputStream、PrintWriter 等),把暂存在内存里的数据交给底层 OS 处理。但操作系统通常仍会缓存这些数据,以提升 I/O 性能 —— 这意味着断电或系统崩溃时,flush() 后的数据仍可能丢失。
如何真正“落盘”?
若业务要求强持久性(例如金融日志、事务提交),需在 flush() 后调用同步方法:
- 对
FileOutputStream:获取通道并调用force(true) - 对
RandomAccessFile:调用getChannel().force(true)或getFD().sync() - 对
PrintWriter/BufferedWriter:先flush(),再通过其底层流(如FileOutputStream)执行同步
典型安全写入示例
以下代码确保内容真正写入磁盘:
立即学习“Java免费学习笔记(深入)”;
try (FileOutputStream fos = new FileOutputStream("data.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
bos.write("hello".getBytes());
bos.flush(); // 清空 Java 缓冲区
fos.getChannel().force(true); // 强制 OS 缓存同步到磁盘
}
注意:该操作会带来性能开销,不应在高频写入场景中滥用。
常见误区提醒
很多人误以为 close() 会自动落盘 —— 实际上 close() 内部会调用 flush(),但同样不保证磁盘写入;System.out.println() 默认不自动 flush(除非构造时指定 autoFlush=true);使用 NIO 的 FileChannel.write() 也需手动 force() 才能保证持久性。


















