linux tail -f 命令可以实现在终端跟踪打印文件输出,但因项目需要将此命令web化。现将代码分享如下:
类图:
原理:LogTail实现Runnable接口,通过RandomAccessFile访问File跟踪读取文件内容,并调用TailNodify发送事件通知。
LogTail
package com.fy.tail.n1;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashSet;
import java.util.Set;
public class LogTail implements Runnable {
/**
* 存储TailLog侦听器
*/
private final Set<TailNotify> listeners = new HashSet<TailNotify>();
/**
* 当读到文件结尾后暂停的时间间隔
*/
private long sampleInterval = 10;
/**
* 设置日志文件
*/
private File logfile;
/**
* 设置是否从头开始读
*/
private boolean startAtBeginning = false;
/**
* 设置tail运行标记
*/
private boolean tailing = false;
public LogTail(long sampleInterval, File logfile, boolean startAtBeginning) {
super();
this.sampleInterval = sampleInterval;
this.logfile = logfile;
this.startAtBeginning = startAtBeginning;
}
/**
* 将侦听器加入TailLog中
*
* @param tailListener
*/
public void add(TailNotify tailListener) {
listeners.add(tailListener);
}
/**
* 通知所有注册的侦听
*
* @param line
*/
protected void notify(String line) {
for (TailNotify tail : listeners) {
tail.notifyMsg(line);
}
}
@Override
public void run() {
long filePointer = 0;
if (this.startAtBeginning) { //判断是否从头开始读文件
filePointer = 0;
} else {
filePointer = this.logfile.length(); //指针标识从文件的当前长度开始。
}
try {
RandomAccessFile file = new RandomAccessFile(logfile, "r"); //创建随机读写文件
while (this.tailing) {
long fileLength = this.logfile.length();
if (fileLength < filePointer) {
file = new RandomAccessFile(logfile, "r");
filePointer = 0;
}
if (fileLength > filePointer) {
file.seek(filePointer);
String line = file.readLine();
while (line != null) {
this.notify(line);
line = file.readLine();
}
filePointer = file.getFilePointer();
}
Thread.sleep(this.sampleInterval);
}
file.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 停止tail
*/
public void stop()
{
this.tailing=false;
}
}
TailNotify:
package com.fy.tail.n1;
/**
* LogTail侦听
* @author youling
*
*/
public interface TailNotify {
/**
* LogTail有日志滚动事件产生后调用此方法
* @return
*/
public void notifyMsg(String msg);
}
TailNotifyImpl:实现了TailNotify
package com.fy.tail.n1;
/**
* tail通知实现
* @author youling
*
*/
public class TailNotifyImpl implements TailNotify {
@Override
public void notifyMsg(String msg) {
if (msg != null && !"".equals(msg)) {
System.out.print(msg);
}
}
}
Main:测试主类
package com.fy.tail.n1;
import java.io.File;
/**
* 测试类
* @author youling
*
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
String filename = "C:\\Users\\youling\\Downloads\\1.txt";
LogTail tailer = new LogTail(1000, new File(filename), true);
tailer.add(new TailNotifyImpl());
new Thread(tailer).start();
Thread.sleep(100 * 1000);
}
}