consolelogger类封装控制台日志追加写入,基于线程安全的printwriter(搭配true参数的filewriter),支持info/error等方法、自动刷新、异常容错及autocloseable资源管理。

用面向对象方式封装控制台日志的实时追加写入,核心是把日志行为抽象成类,结合 FileOutputStream(带 true 参数)或 FileWriter(构造时传 true)实现追加,再通过 PrintStream 或 PrintWriter 做格式化输出。关键在于线程安全、资源管理与复用性。
设计一个可复用的日志器类
定义 ConsoleLogger 类,内部持有一个线程安全的 PrintWriter(底层用追加模式的 FileWriter),提供 info、warn、error 等方法:
- 构造时指定日志文件路径,自动创建父目录
- 使用
new FileWriter(file, true)确保追加写入 - 启用
autoFlush = true,保证每次println立即落盘 - 重写
close()方法,统一释放资源
支持多线程安全写入
控制台日志常被多个线程调用,直接共享 PrintWriter 不安全。推荐两种做法:
- 在每个日志方法内加
synchronized块(锁住自身或写入器实例) - 用
ReentrantLock+tryLock实现更灵活的并发控制 - 避免用
System.out或System.err直接输出——它们不是线程安全的追加目标,且无法定向到文件
实时刷新与异常处理
“实时”依赖及时刷盘,不能只靠缓冲区自然溢出:
- 构造
PrintWriter时传true启用自动 flush - 每次写入后手动调用
pw.flush()(即使 autoFlush=true,某些异常路径下仍需保障) - 捕获
IOException,记录错误到备用输出(如标准错误流),避免日志器崩溃导致业务中断 - 不建议在 finally 块中 close——应由使用者显式调用,或配合
try-with-resources(需让类实现AutoCloseable)
简单示例:初始化与使用
代码片段示意结构(省略包声明和细节异常处理):
public class ConsoleLogger implements AutoCloseable {
private final PrintWriter writer;
public ConsoleLogger(String filePath) throws IOException {
File file = new File(filePath);
file.getParentFile().mkdirs();
this.writer = new PrintWriter(
new FileWriter(file, true), // 追加模式
true // autoFlush
);
}
public void info(String msg) {
writer.println("[" + new Date() + "] INFO: " + msg);
}
public void error(String msg) {
writer.println("[" + new Date() + "] ERROR: " + msg);
}
@Override
public void close() {
if (writer != null) writer.close();
}
}
// 使用:
try (ConsoleLogger log = new ConsoleLogger("app.log")) {
log.info("服务启动");
log.error("连接超时");
} // 自动关闭











