java可通过system.setout()重定向system.out到自定义printstream实现日志写入文件,需注意路径可写、启用追加模式、线程同步及恢复原始输出,生产环境更推荐slf4j等日志框架。

Java 中可以通过 System.setOut() 方法将 System.out 重定向到任意 PrintStream 实例,从而实现控制台输出的捕获或写入文件等操作。
创建自定义 PrintStream 指向文件
最常见需求是把日志保存到文件而非打印到控制台。只需构造一个指向文件的 PrintStream,再用 System.setOut() 替换默认输出流:
- 确保目标文件路径可写,否则会抛出
FileNotFoundException - 建议使用
new PrintStream(new FileOutputStream("app.log", true))启用追加模式,避免覆盖历史日志 - 注意:一旦重定向,所有
System.out.println()都会写入该文件,包括第三方库的输出
保留原始输出并同时写入文件(双写)
若需既在控制台显示又记录到文件,可封装一个代理 PrintStream,内部委托给两个底层流:
- 继承
PrintStream或使用装饰器模式,重写write()、print()等关键方法 - 在每个写入操作中,分别调用控制台原
System.out和文件PrintStream - 务必同步写入操作(尤其多线程场景),避免日志错乱;可用
synchronized块或PrintStream自带的自动刷新机制
临时重定向 + 恢复原始输出
测试或调试时经常需要临时重定向,之后恢复控制台输出。关键在于保存原始 PrintStream 引用:
- 启动时执行
PrintStream originalOut = System.out; - 重定向后,通过
System.setOut(originalOut)即可还原 - 不要反复 new 新的
PrintStream再设回去——原始System.out是 JVM 初始化时创建的唯一实例
注意事项与替代方案
直接修改 System.out 属于全局副作用,生产环境慎用:
- 多个模块可能依赖
System.out行为,重定向易引发不可预期问题 - Web 应用或容器环境(如 Tomcat)中,
System.out通常已重定向到日志系统,自行修改可能冲突 - 更推荐使用成熟日志框架(如 SLF4J + Logback),通过配置控制输出目标,语义清晰且线程安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











