Java实时读取日志文件
古怪的需求#
在实习的公司碰到一个古怪的需求:在一台服务器上写日志文件,每当日志文件写到一定大小时,比如是1G,会将这个日志文件改名成另一个名字,并新建一个与原文件名相同的日志文件,再往这个新建的日志文件里写数据;要求写一个程序能实时地读取日志文件中的内容,并且不能影响写操作与重命名操作。
RandomAccessFile类中seek方法可以从指定位置读取文件,可以用来实现文件实时读取。JDK文档对RandomAccessFile的介绍
Instances of this class support both reading and writing to a random access file. A random access file behaves like a large array of bytes stored in the file system. There is a kind of cursor, or index into the implied array, called the file pointer; input operations read bytes starting at the file pointer and advance the file pointer past the bytes read. If the random access file is created in read/write mode, then output operations are also available; output operations write bytes starting at the file pointer and advance the file pointer past the bytes written. Output operations that write past the current end of the implied array cause the array to be extended.
在每一次读取后,close一下就不会影响重命名操作了。
编码实现#
代码参考Java实时监控日志文件并输出,LogTailer.java。
写日志文件,每秒写200条记录,并且记录写的时间
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogReader implements Runnable {
	private File logFile = null;
	private long lastTimeFileSize = 0; // 上次文件大小
	private static SimpleDateFormat dateFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	public LogReader(File logFile) {
		this.logFile = logFile;
		lastTimeFileSize = logFile.length();
	}
	/**
	 * 实时输出日志信息
	 */
	public void run() {
		while (true) {
			try {
				long len = logFile.length();
				if (len < lastTimeFileSize) {
					System.out.println("Log file was reset. Restarting logging from start of file.");
					lastTimeFileSize = len;
				} else if(len > lastTimeFileSize) {
					RandomAccessFile randomFile = new RandomAccessFile(logFile, "r");
					randomFile.seek(lastTimeFileSize);
					String tmp = null;
					while ((tmp = randomFile.readLine()) != null) {
						System.out.println(dateFormat.format(new Date()) + "\t"
								+ tmp);
					}
					lastTimeFileSize = randomFile.length();
					randomFile.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
实时读取日志文件,每隔1秒读一次
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogReader implements Runnable {
	private File logFile = null;
	private long lastTimeFileSize = 0; // 上次文件大小
	private static SimpleDateFormat dateFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	public LogReader(File logFile) {
		this.logFile = logFile;
		lastTimeFileSize = logFile.length();
	}
	/**
	 * 实时输出日志信息
	 */
	public void run() {
		while (true) {
			try {
				RandomAccessFile randomFile = new RandomAccessFile(logFile, "r");
				randomFile.seek(lastTimeFileSize);
				String tmp = null;
				while ((tmp = randomFile.readLine()) != null) {
					System.out.println(dateFormat.format(new Date()) + "\t"
							+ tmp);
				}
				lastTimeFileSize = randomFile.length();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
开启写线程、读线程,将实时信息打印在控制台。
import java.io.File;
public class RunRun {
	public static void main(String[] args) {
		File logFile = new File("mock.log");
		Thread wthread = new Thread(new LogWrite(logFile));
		wthread.start();
		Thread rthread = new Thread(new LogReader(logFile));
		rthread.start();
	}
}
在读写的过程中,我们可以手动将mock.log文件重命名,发现依旧可以实时读。
Java实时读取日志文件的更多相关文章
- RandomAccessFile实时读取大文件(转)
		最近有一个银行数据漂白系统,要求操作人员在页面调用远端Linux服务器的shell,并将shell输出的信息保存到一个日志文件,前台页面要实时显示日志文件的内容.这个问题难点在于如何判断哪些数据是新增 ... 
- Java快速读取大文件
		Java快速读取大文件 最近公司服务器监控系统需要做一个东西来分析Java应用程序的日志. 第一步探索: 首先我想到的是使用RandomAccessFile,因为他可以很方便的去获取和设置文件指针,下 ... 
- Linux 实时查看日志文件动态内容
		tailf 27.log | grep 'Classcomment/praise' 'Classcomment/praise' 接口名:查看请求固定接口的时间,实时 tai ... 
- 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息
		1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ... 
- 五种方式让你在java中读取properties文件内容不再是难题
		一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ... 
- java中读取特殊文件的类型
		java中读取特殊文件的类型: 第一种方法(字符拼接读取): public static String getType(String s){ String s1=s.substring(s.index ... 
- tail -f 实时查看日志文件 linux查看日志后100行
		tail -f 实时查看日志文件 tail -f 日志文件logtail - 100f 实时查看日志文件 后一百行tail -f -n 100 catalina.out linux查看日志后100行搜 ... 
- Storm 实时读取本地文件操作(模拟分析网络日志)
		WebLogProduct 产生日志类 package top.wintp.weblog; import java.io.FileNotFoundException; import java.io.F ... 
- flume读取日志文件并存储到HDFS
		配置hadoop环境 配置flume环境 配置flume文件 D:\Soft\apache-flume-1.8.0-bin\conf 将 flume-conf.properties.template ... 
随机推荐
- FSM 浅谈
			之前写过一篇关于状态机的,上一篇讲过的我也就不再罗嗦了,不知道欢迎去查看我的上一篇随笔,主要是感觉上次自己封装的还是不行,所以又进行修改了一番! 我本人是个菜鸟,最开始接触状态机的时候,状态机一个可厉 ... 
- ASP.NET连接远程Oracle数据库,提示试图加载格式不正确的程序
			VS调试远程连接Oracle数据库,一直报错 由于本地计算机是64位的操作系统,而且也确定安装的Oracle客户端是64位的 ,但是一直提示这个错误. 试了很多方法,终于发现可能是 不能在VS中调试的 ... 
- Linux之源码包安装软件
			安装准备 安装c语言编辑器 gcc 压缩包 node-v6.2.0-linux-x64.tar.gz 源码包保存位置 /usr/local/src/ 源码包安装位置 /us ... 
- nginx+winsw windows服务
			1.下载Nginx:http://nginx.org/en/download.html 2.下载winsw配置包:http://files.cnblogs.com/files/objecttozero ... 
- asp.net identity 2.2.0 中角色启用和基本使用(三)
			创建控制器 第一步:在controllers文件夹上点右键>添加>控制器, 我这里选的是“MVC5 控制器-空”,名称设置为:RolesAdminController.cs 第二步:添加命 ... 
- 作业二--注册GitHub的过程
			第一步:打开GitHub官网https://github.com/,在界面中输入账号名称.邮箱.密码,然后点击注册按钮. 第二步:注册完成后,选择Free免费账号完成初始设置. 第三步:验证邮箱,打开 ... 
- 使用ACE_Task管理线程
			为什么要使用ACE_Task来管理线程 从C#转到C++后,感觉到C++比C#最难的地方,就是在系统编程时,C#中有对应的类库,我接触到一个类后,就可以通过这个类,知道很多相关的功能.而在C++中,必 ... 
- java提高篇(一)-----理解java的三大特性之封装
			从大二接触java开始,到现在也差不多三个年头了.从最基础的HTML.CSS到最后的SSH自己都是一步一个脚印走出来的,其中开心过.失落过.寂寞过.虽然是半道出家但是经过自己的努力也算是完成了“学业” ... 
- Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架
			C#LightEvil之前提供了很多和Unity结合的例子,都是采用把脚本文件放置在StreamingAssets中的方法. 这样可以利用Unity的特性,放在这个目录中的CS文件会被编译器编译,我们 ... 
- H5常用代码:适配方案2
			前面的通过视口做适配的方案由于安卓低版本原生浏览器的存在,在许多场合不尽如人意,会在低版本安卓上出现,不缩放,手动缩放未禁止的问题. 于是出现了第二种适配方案,既然通过视口缩放可以兼容,那为什么不直接 ... 
