文件监听 之 Tailer
Apache Commons IO库的Tailer类是一个用于实时监控文件内容变化的工具,它通过线程方式模拟Unix的tail -f命令,持续追踪文件新增内容,适用于日志监控、实时数据处理等场景。以下是其核心功能、使用方法及注意事项的详细说明:
一、核心功能
-
实时监控文件变化
- 通过后台线程定期检查文件内容,发现新增行时触发回调。
- 支持从文件末尾(默认)或开头开始监控。
-
灵活的配置选项
- 延迟时间(
delayMillis):控制检查文件更新的间隔(毫秒),默认1秒。 - 字符集(
Charset):指定文件编码(如UTF-8),避免乱码。 - 缓冲区大小(
bufSize):优化大文件读取性能,默认8KB。 - 文件轮转处理(
reOpen):文件被切割(如日志轮转)时重新打开文件。
- 延迟时间(
-
事件回调机制
- 通过
TailerListener接口或其适配器TailerListenerAdapter接收文件变化事件,包括:handle(String line):每读取到一行新内容时触发。fileNotFound():文件未找到时触发。fileRotated():文件被轮转时触发。endOfFileReached():到达文件末尾时触发。handle(Exception ex):处理读取过程中的异常。
- 通过
二、使用方法
1. 基本用法
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import java.io.File;
public class BasicTailerExample {
public static void main(String[] args) {
File logFile = new File("/var/log/app.log");
TailerListenerAdapter listener = new TailerListenerAdapter() {
@Override
public void handle(String line) {
System.out.println("New log entry: " + line);
}
@Override
public void fileNotFound() {
System.err.println("Error: Log file not found!");
}
};
// 创建Tailer实例,延迟1秒检查文件变化
Tailer tailer = new Tailer(logFile, listener, 1000);
// 启动监控线程(设置为守护线程,随主线程退出)
Thread thread = new Thread(tailer);
thread.setDaemon(true);
thread.start();
// 保持程序运行(示例中简单休眠,实际需根据场景调整)
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2. 高级配置
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import java.io.File;
import java.nio.charset.StandardCharsets;
public class AdvancedTailerExample {
public static void main(String[] args) {
File logFile = new File("/var/log/app.log");
TailerListenerAdapter listener = new TailerListenerAdapter() {
@Override
public void handle(String line) {
System.out.println("Processed: " + line);
}
};
// 自定义配置:延迟500ms,UTF-8编码,从文件末尾开始,支持文件轮转
Tailer tailer = new Tailer(
logFile,
StandardCharsets.UTF_8,
listener,
500,
true,
true,
8192 // 缓冲区大小(字节)
);
Thread thread = new Thread(tailer);
thread.start();
}
}
3. 使用Builder模式(推荐)
Apache Commons IO 2.21.0及以上版本推荐使用Tailer.Builder构建实例,代码更简洁:
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import java.io.File;
import java.nio.charset.StandardCharsets;
public class BuilderTailerExample {
public static void main(String[] args) {
File logFile = new File("/var/log/app.log");
TailerListenerAdapter listener = new TailerListenerAdapter() {
@Override
public void handle(String line) {
System.out.println("Builder Log: " + line);
}
};
Tailer tailer = Tailer.builder()
.setFile(logFile)
.setCharset(StandardCharsets.UTF_8)
.setListener(listener)
.setDelayMillis(500)
.setEnd(true)
.setReOpen(true)
.setBufferSize(8192)
.get();
Thread thread = new Thread(tailer);
thread.start();
}
}
三、关键注意事项
-
文件权限
- 确保程序有权限读取目标文件,否则会触发
fileNotFound()事件。
- 确保程序有权限读取目标文件,否则会触发
-
文件轮转处理
- 若日志被切割(如
logrotate),需设置reOpen=true或覆盖fileRotated()方法重新打开文件。
- 若日志被切割(如
-
性能优化
- 延迟时间:根据实时性需求调整
delayMillis,高频日志可设为100-500ms,低频日志可设为1-5秒。 - 缓冲区大小:大文件或高吞吐量场景可增大
bufSize(如32KB或64KB)。
- 延迟时间:根据实时性需求调整
-
异常处理
- 覆盖
handle(Exception ex)方法,避免未捕获异常导致线程终止。例如:@Override public void handle(Exception ex) { System.err.println("Error reading file: " + ex.getMessage()); }
- 覆盖
-
资源释放
- 长时间运行的应用需在关闭时调用
tailer.stop()(需扩展Tailer类或通过其他方式控制),或设置线程为守护线程(setDaemon(true))随主线程退出。
- 长时间运行的应用需在关闭时调用
-
多线程安全
Tailer本身是线程安全的,但TailerListener的实现需确保线程安全,避免共享变量竞争。
四、适用场景
- 实时日志监控:监控Nginx、Tomcat等应用的日志文件,实时输出错误或关键信息。
- ETL流程:实时处理数据文件的新增内容,触发数据清洗或入库操作。
- 轻量级日志分析工具:开发简单的日志查看器,支持实时刷新和关键词过滤。
五、版本兼容性
- Apache Commons IO 2.0+:支持基本功能。
- Apache Commons IO 2.21.0+:推荐使用
Tailer.Builder构建实例,代码更简洁。
通过Tailer和TailerListenerAdapter,可以高效实现文件内容变化的实时监控,且代码简洁易维护。生产环境中建议结合线程池和日志框架(如SLF4J)进一步优化。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19296113

浙公网安备 33010602011771号