使用PrintWriter时数据无法写入文件?构造方法差异及原因解析
嘿,这个问题我之前踩过坑,咱们一步步来搞清楚原因~
核心根源:PrintWriter的“懒写入”缓冲区机制
不管用哪种构造方法创建PrintWriter,它都会用一块内存缓冲区暂存要写入的数据——毕竟频繁直接写硬盘太耗性能了。只有满足以下条件之一,缓冲区里的内容才会真正落地到文件:
- 缓冲区被填满(默认大小一般是8KB,你写的那点内容显然远没到这个阈值)
- 你手动调用了
out.flush()方法,强制把缓冲区内容刷入文件 - 你调用了
out.close()方法(close操作会自动触发flush) - 如果开启了自动刷新(autoFlush=true),调用
println()、printf()这类带换行/格式化的方法时会自动flush(划重点:print()方法就算开了autoFlush也不会触发刷新!)
两种构造方法的差异拆解
咱们来扒一扒你用的两个构造逻辑:
PrintWriter(File source)
这个构造直接基于文件对象创建PrintWriter,底层链路是FileOutputStream→OutputStreamWriter→PrintWriter。默认情况下没有开启自动刷新(autoFlush=false),而你的代码里只调用了out.print(),既没手动flush也没close,数据就一直“躺”在缓冲区里,程序跑完也没机会写入文件。PrintWriter(new BufferedWriter(new FileWriter(source)))
这个是基于字符流Writer来封装PrintWriter,中间多了一层BufferedWriter做缓冲——但本质上它的缓冲区规则和第一种完全一致!你说这个能正常工作,大概率是你实际代码里要么手动调用了close()/flush(),要么用了try-with-resources语法(自动帮你关闭流),只是代码片段没展示出来。如果和第一段代码一样只调用print()就结束,它同样写不进文件。
快速解决办法
想要第一段代码正常输出,只需要补上flush或close操作就行,推荐用更安全的try-with-resources(自动管理资源,不用担心漏关流):
File source = new File("notebook.txt"); try (PrintWriter out = new PrintWriter(source)) { out.print("I hate Mondays"); } // 这里会自动执行close,触发flush,数据就顺利写入文件了
或者手动在finally块里关闭(避免异常导致漏关):
File source = new File("notebook.txt"); PrintWriter out = new PrintWriter(source); try { out.print("I hate Mondays"); } finally { out.close(); }
如果想开启自动刷新(仅对println()等方法生效),可以用带autoFlush参数的构造:
// 开启自动刷新模式 PrintWriter out = new PrintWriter(source, true); out.println("I hate Mondays"); // 调用println会自动触发flush
内容的提问来源于stack exchange,提问作者hoapham

