printstream和printwriter均支持自动刷新但触发条件不同:前者在println/printf/format或写入'\n'时刷新,后者仅在println/printf/format时刷新;编码上printstream依赖平台默认字节编码,printwriter可通过outputstreamwriter显式指定字符集,更可控。

PrintStream 和 PrintWriter 都支持自动刷新,但触发条件和底层语义不同;编码处理上,PrintStream 用平台默认字节编码,PrintWriter 可显式指定字符集,更可控。
自动 flush 的触发时机不一样
两者虽都可通过构造参数 autoFlush=true 启用自动刷新,但实际调用 flush() 的时机有明确区别:
-
PrintStream:只要调用
println()、printf()、format(),或单独写入一个'\n'(比如write('\n')或print("\n")),就会触发刷新 -
PrintWriter:仅在调用
println()、printf()、format()时刷新;用write("\n")或write('\n')不会触发自动刷新 - 注意:自动刷新依赖底层流是否真正实现
flush()。若包装的是无缓冲的流(如直接包装FileOutputStream),即使设了autoFlush=true,也无实质效果
编码处理层级完全不同
PrintStream 工作在字节层,PrintWriter 工作在字符层,这导致编码行为本质不同:
- PrintStream 把所有字符按平台默认编码(如 Windows 是 GBK,Linux/macOS 多为 UTF-8)转成字节再输出,不可配置,跨平台易乱码
-
PrintWriter 操作的是字符,本身不处理编码;但可通过包装
OutputStreamWriter显式指定字符集(如new PrintWriter(new OutputStreamWriter(out, "UTF-8"))),保证中文等多语言安全 - PrintWriter 的
println()使用系统行分隔符(System.lineSeparator()),而非固定'\n';PrintStream 则对'\n'敏感,行为更“底层”
错误检测方式相似但异常策略不同
二者都不在方法签名中抛出 IOException,但背后机制有差异:
- PrintStream 所有写操作内部静默捕获 I/O 异常,并置位错误标志;必须调用
checkError()主动判断 - PrintWriter 在多数构造方式下(如传入
File或文件名)也不抛异常,但若包装的是声明异常的Writer(如带异常的OutputStreamWriter),其print/println方法仍可能抛出IOException - 无论哪种,推荐统一用
checkError()做事后检查,而不是依赖异常中断流程
选哪个更合适?看场景
没有绝对优劣,关键匹配用途:
- 控制台输出(如
System.out)用PrintStream—— 简单、兼容性好、无需关心编码 - 写文本文件、尤其含中文或需跨平台时,优先用
PrintWriter,并显式指定 UTF-8 编码 - 网络通信中二者常可互换(如 Socket 输出流),但若协议要求严格换行行为或需稳定编码,PrintWriter + 明确 charset 更稳妥
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











