环境; SpringMVC + WebSocket
实现方式: 通过RandomAccessFile实现对文件的监控
public class FileTailWatcherRun implements Runnable {
/**
* 缓存近10条
*/
private final LimitQueue<String> limitQueue = new LimitQueue<>(100);
private RandomAccessFile randomFile;
/**
* 是否已经开始执行
*/
private boolean start = false;
private WebSocketSession session;
private FileTailWatcherRun(File file,WebSocketSession session) {
this.session = session;
try{
this.randomFile = new BufferedRandomAccessFile(file,"r");
if (file.length() > 0) {
this.startRead();
}
}catch (IOException e){
e.printStackTrace();
}
}
public static FileTailWatcherRun getInstance(File file,WebSocketSession session){
return new FileTailWatcherRun(file,session);
}
private void startRead() throws IOException {
long len = randomFile.length();
long start = randomFile.getFilePointer();
long nextEnd = start + len - 1;
randomFile.seek(nextEnd);
int c;
int count = 0;
while (nextEnd > start && count<100) {
if (limitQueue.full()) {
break;
}
c = randomFile.read();
if (c == '\n' || c == '\r') {
count++;
this.readLine();
nextEnd--;
}
nextEnd--;
randomFile.seek(nextEnd);
if (nextEnd == 0) {
// 当文件指针退至文件开始处,输出第一行
this.readLine();
break;
}
}
// 移动到尾部
randomFile.seek(len);
}
private void readLine() throws IOException {
String line = randomFile.readLine();
if (line != null) {
line = new String(line.getBytes("iso8859-1"),"utf-8");
limitQueue.offerFirst(line);
sendMsg(line);
}
}
/**
* 读取文件内容
*
* @throws IOException IO
*/
private void read() throws IOException {
final long currentLength = randomFile.length();
final long position = randomFile.getFilePointer();
if (0 == currentLength || currentLength == position) {
// 内容长度不变时忽略此次
return;
} else if (currentLength < position) {
// 如果内容变短,说明文件做了删改,回到内容末尾
randomFile.seek(currentLength);
return;
}
String tmp;
while ((tmp = randomFile.readLine()) != null) {
tmp = new String(tmp.getBytes("iso8859-1"),"utf-8");
limitQueue.offer(tmp);
sendMsg(tmp);
}
// 记录当前读到的位置
this.randomFile.seek(currentLength);
}
/**
* 开始监听
*/
public void start() {
if (this.start) {
return;
}
this.start = true;
new Thread(this).start();
}
@Override
public void run() {
while (this.start) {
try {
this.read();
} catch (IOException e) {
sendMsg("读取文件发生异常:" + e.getMessage());
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
this.close();
}
public void close() {
this.start = false;
if(this.randomFile != null){
try {
this.randomFile.close();
} catch (IOException e) {
}
}
}
public synchronized void sendMsg(String msg){
if(!this.session.isOpen()){
this.start = false;
return;
}
MySpringWebSocketHandle.sendMsg(msg,this.session);
}
}