可通过System.setOut()将System.out重定向至文件,需用指定UTF-8编码、可选追加模式的PrintStream包装FileOutputStream,并注意保存原输出流以便恢复。
可以通过 system.setout() 将标准输出(system.out)重定向到一个文件,核心是用 printstream 包装一个指向本地文件的 fileoutputstream。
准备一个带缓冲的 PrintStream 指向文件
创建文件输出流时建议使用 FileOutputStream 并传入 true 开启追加模式(可选),再用它构造 PrintStream。为避免中文乱码,推荐显式指定字符集(如 UTF-8):
- 确保目标目录存在,否则会抛出
FileNotFoundException - 使用
new PrintStream(new FileOutputStream("output.txt", true), true, "UTF-8")可启用自动刷新 + UTF-8 编码 - 如果只是覆盖写入,去掉第二个参数
true即可
调用 System.setOut() 替换标准输出流
将构造好的 PrintStream 传给 System.setOut(),之后所有 System.out.println() 等操作都会写入该文件:
- 此操作是全局生效的,影响当前 JVM 中所有后续对
System.out的调用 - 注意:重定向后控制台不再显示输出,除非你同时保留原
PrintStream并手动双写 - 可在程序退出前用
System.setOut(originalOut)恢复原始输出(建议提前保存)
完整示例代码
注意关闭资源和异常处理:
PrintStream originalOut = System.out;
try (PrintStream fileOut = new PrintStream(
new FileOutputStream("log.txt", true),
true,
"UTF-8")) {
System.setOut(fileOut);
System.out.println("这行会写入 log.txt");
System.out.println("中文也能正常显示");
} catch (IOException e) {
e.printStackTrace();
// 出错时恢复输出,避免后续日志丢失
System.setOut(originalOut);
}
执行后,控制台无输出,内容全部写入 log.txt(路径为相对当前工作目录)。
注意事项与常见问题
实际使用中容易忽略以下细节:
-
路径问题:相对路径基于 JVM 启动时的工作目录,建议用绝对路径或先确认
new File(".").getAbsolutePath() -
线程安全:
PrintStream是线程安全的,多线程写入无需额外同步 -
不自动刷新:即使开启 auto-flush,某些场景(如异常退出)仍可能丢失最后几行,关键日志建议手动调用
System.out.flush() - 替代方案:长期运行程序建议用 Log4j、SLF4J 等日志框架,更灵活可控










