用RandomAccessFile实现linux tail命令效果

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);
	}
}



上面是实现在终端跟踪打印文件输出核心代码。此代码结合《基于 HTTP 长连接的“服务器推”技术》(见本博另外的 转载连接),可实现web化的tail -f 功能。读者可自行学习实现。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值