[Rainy开发笔记]使用RandomAccessFile实现的Tail

怎么实现一个tail,一开始的想法是在本地或者内存记录下当前读取到的文件的位置,然后每隔一定时间检测下看看是否有更新,想好了之后就准备开始写,但是按照习惯,能偷懒绝对不动手的原则首先google了一把,果不其然,网上已经有实现方案了,二话不说,拷贝过来进行修改。

思路就是我刚才的思路,但是接下来这个思路有个问题,就是轮训的效率并不高,而且读取不是实时的,因为我要做远程的这种文件同步,延迟性的tail肯定不可取,所以加入jdk7的新特性,进行文件监控,这样每次文件有更新,将会第一时间被通知到,然后进行相关的tail操作,核心代码如下:

public void run() {
		long filePointer = 0;

		if (this.startAtBeginning) {
			filePointer = 0;
		} else {
			filePointer = this.targetFile.length();
		}

		try {
			this.tailing = true;
			RandomAccessFile file = new RandomAccessFile(targetFile, "r");
			while (this.tailing) {
				WatchKey key = watchService.take();
				for (WatchEvent<?> event : key.pollEvents()) {
					System.out.println("[Tail monitor ] " + event.context() + "  " + event.kind() + " was triggered");
				}
				long fileLength = this.targetFile.length();
				System.out.println("fileLength : " + fileLength);
				if (fileLength == 0) {
					System.out.println("fileLength : " + fileLength);
					Thread.sleep(sampleInterval);
					System.out.println("Sleep : " + sampleInterval);
					key.reset();
					continue;
				}
				if (fileLength < filePointer && fileLength != 0) {
					file = new RandomAccessFile(targetFile, "r");
					filePointer = 0;
				}
				if (fileLength > filePointer) {
					file.seek(filePointer);
					String line = file.readLine();
					while (line != null) {
						line = new String(line.getBytes("8859_1"), tailFileCharSet);
						this.fireNewLogFileLine(targetFile.getName(), line);
						line = file.readLine();
					}
					filePointer = file.getFilePointer();
				}
				key.reset();
			}
			file.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

具体的远程tail,请移步

http://git.oschina.net/grom/rainy

然后在测试的时候发觉到一个很坑爹的问题,读取出来的日志居然有乱码,经过排查,RandomAccessFile有下面的一句

 switch (c = read()) {

C是个char类型,这不是坑爹么,不读成byte,读成char,那你使用的什么编码?算了,按理说应该是8859-1,直接转下试试,果然成功

line = new String(line.getBytes("8859_1"), tailFileCharSet);


你可能感兴趣的:([Rainy开发笔记]使用RandomAccessFile实现的Tail)