printstream打印格式化日志到文件的核心是:用fileoutputstream包装文件路径并启用自动刷新(true),再调用printf方法输出带占位符内容;它基于字节流,语法简洁但需注意中文编码、线程安全及生产级功能缺失。

Java 中用 PrintStream 打印格式化日志到文件,核心是创建一个指向文件的 PrintStream 实例,再用它的 printf(或 format)方法输出带占位符的日志内容。它底层基于字节流,支持自动刷新(可选),语法简洁,适合轻量级日志记录。
1. 创建带自动刷新的 PrintStream 文件输出流
关键点:必须用 FileOutputStream 包装文件路径,并传入 true 启用自动刷新(否则可能看不到实时日志)。
- 推荐使用
new FileOutputStream(file, true)追加模式,避免覆盖旧日志 - 构造时传
true作为第二个参数,使每次println/printf后自动刷入磁盘 - 务必在用完后调用
close()(建议 try-with-resources)
2. 使用 printf 进行格式化输出
PrintStream.printf() 行为与 System.out.printf() 完全一致,支持标准格式化符号:
-
%s:字符串(如线程名、方法名) -
%d:整数(如行号、计数) -
%.3f:保留三位小数的浮点数 -
%tF或%tT:日期时间(需传入java.util.Date或long时间戳) - 每条日志建议包含时间、级别、类/方法、消息,例如:
[%tF %tT] [%s] %s: %s%n
3. 完整示例代码(含异常处理和资源管理)
以下是一个安全、可直接运行的日志工具片段:
import java.io.*;
public class FileLogger {
private final PrintStream logStream;
public FileLogger(String filePath) throws FileNotFoundException {
// 追加写入 + 自动刷新
this.logStream = new PrintStream(
new FileOutputStream(filePath, true), true);
}
public void info(String clazz, String method, String msg) {
logStream.printf("[%tF %tT] [INFO] [%s.%s] %s%n",
System.currentTimeMillis(), System.currentTimeMillis(),
clazz, method, msg);
}
public void error(String clazz, String method, String msg, Throwable e) {
logStream.printf("[%tF %tT] [ERROR] [%s.%s] %s%n",
System.currentTimeMillis(), System.currentTimeMillis(),
clazz, method, msg);
if (e != null) {
e.printStackTrace(logStream); // 错误堆栈也输出到同一文件
}
}
public void close() {
logStream.close();
}
}
// 使用方式:
// try (FileLogger logger = new FileLogger("app.log")) {
// logger.info("UserService", "login", "User logged in");
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
4. 注意事项与替代建议
PrintStream 简单够用,但不支持日志级别控制、异步写入、滚动归档等高级功能:
- 中文乱码?确保文件编码与 IDE/终端一致(如 UTF-8),
PrintStream默认用平台编码,必要时改用OutputStreamWriter+BufferedWriter配合指定 charset - 高并发场景下性能一般,多线程写入需额外同步(
printf本身线程安全,但日志内容交叉仍可能发生) - 生产环境更推荐 Log4j2、Logback 等成熟框架,它们原生支持异步、过滤、按大小/时间滚动、JSON 输出等
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











