You need to enable JavaScript to run this app. PrintWriter写文件无输出但PrintStream写入正常,是什么原因?
优惠活动
大模型
产品
解决方案
定价
更多

PrintWriter写文件无输出但PrintStream写入正常,是什么原因?

两种写文件方式效果差异的根本原因

两种实现的结果不一样,核心是不同链路下的内存缓冲刷盘触发逻辑完全不同,和PrintWriter、PrintStream的类本身没有本质关联。

第一种写法为什么看不到写入结果

你用的第一种实现的完整数据流转链路是:
PrintWriter -> BufferedWriter -> FileWriter -> 磁盘文件
问题就出在链路中间套的BufferedWriter上:

  • 这个类的设计初衷是减少高频磁盘IO,默认会在JVM内存里开一块8KB大小的缓冲区,所有你通过println写的内容,都会先暂存在这块内存里,不会立刻落到磁盘。
  • 只有满足三个条件中的任意一个,缓冲区里的内容才会真正写到磁盘:
    • 缓冲区攒够了8KB的内容,自动触发批量刷盘
    • 手动调用flush()方法强制把缓冲区内容刷出去
    • 调用close()方法关闭流(close执行时会先把所有缓冲区剩余内容刷到磁盘,再释放系统资源)
      你只写了几个字节的"Hi",远达不到缓冲区的触发阈值,代码里既没手动flush、也没关流,内容就一直卡在JVM内存的缓冲区里,根本没走到磁盘层面,自然看不到文件里的写入效果。

第二种写法为什么能正常写入

第二种实现的完整数据流转链路是:
PrintStream -> 内部字符缓冲区 -> 字节编码层 -> 磁盘文件
逻辑差异的核心点是:

  • PrintStream在每次执行println写入换行符时,不会等缓冲区攒够批量大小再统一输出,而是立刻把内部暂存的字符内容编码成字节,直接下发到底层的文件输出流。
  • 你写入的"Hi"加换行符总共才3个字节,因为println触发了立刻下发的逻辑,内容在代码执行的瞬间就已经提交到操作系统的文件描述符里;就算没有显式调用close,当程序正常跑完退出时,操作系统也会自动把文件描述符里的缓存内容刷到磁盘,自然就能在文件里看到对应的文本。

补充提示

如果给第一种写法补上一句out.close()或者out.flush(),哪怕还是用PrintWriter套BufferedWriter的写法,也能正常把内容写到文件里,本质就是手动触发了缓冲区的刷盘动作。这也是Java开发写文件时的经典踩坑点:带内存缓冲的流如果忘记手动flush或close,在短文本写入的场景下,就很容易出现文件生成了但内容是空的情况。

内容的提问来源于stack exchange,提问作者esnoopy808

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.08 20:15:03