古怪的需求#

在实习的公司碰到一个古怪的需求:在一台服务器上写日志文件,每当日志文件写到一定大小时,比如是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实时读取日志文件的更多相关文章

  1. RandomAccessFile实时读取大文件(转)

    最近有一个银行数据漂白系统,要求操作人员在页面调用远端Linux服务器的shell,并将shell输出的信息保存到一个日志文件,前台页面要实时显示日志文件的内容.这个问题难点在于如何判断哪些数据是新增 ...

  2. Java快速读取大文件

    Java快速读取大文件 最近公司服务器监控系统需要做一个东西来分析Java应用程序的日志. 第一步探索: 首先我想到的是使用RandomAccessFile,因为他可以很方便的去获取和设置文件指针,下 ...

  3. Linux 实时查看日志文件动态内容

    tailf 27.log | grep 'Classcomment/praise'               'Classcomment/praise' 接口名:查看请求固定接口的时间,实时 tai ...

  4. 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息

    1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ...

  5. 五种方式让你在java中读取properties文件内容不再是难题

    一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ...

  6. java中读取特殊文件的类型

    java中读取特殊文件的类型: 第一种方法(字符拼接读取): public static String getType(String s){ String s1=s.substring(s.index ...

  7. tail -f 实时查看日志文件 linux查看日志后100行

    tail -f 实时查看日志文件 tail -f 日志文件logtail - 100f 实时查看日志文件 后一百行tail -f -n 100 catalina.out linux查看日志后100行搜 ...

  8. Storm 实时读取本地文件操作(模拟分析网络日志)

    WebLogProduct 产生日志类 package top.wintp.weblog; import java.io.FileNotFoundException; import java.io.F ...

  9. flume读取日志文件并存储到HDFS

    配置hadoop环境 配置flume环境 配置flume文件 D:\Soft\apache-flume-1.8.0-bin\conf 将 flume-conf.properties.template ...

随机推荐

  1. [leetcode 48] rotate image

    1 题目 You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwi ...

  2. XHEditor(MVC4+DWZ) 部分问题的解决

    百度上下载了xheditor1.2.1 一.使用方法: 1.把解压的目录copy到VS中; 2.在需要用的View页面中引用js <script src="~/xheditor/xhe ...

  3. Kylin查询性能低下原因分析

    在处理指数行情数据时(IDXD),我遇到一个KYLIN性能查询低下的问题,非常奇怪.经过一番研究发现了其中的原因并顺利解决: 症状: select count(*) from sensitop.idx ...

  4. 开始VS 2012 中LightSwitch系列的第1部分:表中有什么?描述你的数据

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 1: What’s in a Table? Describing Your Data [原文发表时间]  ...

  5. Java多线程13:读写锁和两种同步方式的对比

    读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...

  6. Java多线程系列--“JUC锁”05之 非公平锁

    概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...

  7. js函数实现转换css中常用的颜色编码

    //转换css中常用颜色编码 var toRGB = function (val){ var reg1 = /^#([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i; ...

  8. 赴美工作常识(Part 4 - 面试)

    最近跟同事讨论面试的事情比较多,所以就综合大家所说的列举几条面试建议吧.这些建议是针对中国候选人应聘美国职位而写的,但适用范围可能更广.假若你实际的实力是 X,面试官感知到你的实力是 Y,这些建议既不 ...

  9. 第二章 深入 C# 数据类型

    第二章 深入 C# 数据类型 1.封装又称信息隐藏,是指利用抽象数据类型将数据和数据的操作结合在一起,使其构成一个不可分割的独立实体,尽可能的隐藏内部的细节,只保留一些对外接口,使之于外部发生联系. ...

  10. Java程序员的日常 —— Java类加载中的顺序

    之前说过Java中类的加载顺序,这次看完继承部分,就结合继承再来说说类的加载顺序. 继承的加载顺序 由于static块会在首次加载类的时候执行,因此下面的例子就是用static块来测试类的加载顺序. ...