古怪的需求

在实习的公司碰到一个古怪的需求:在一台服务器上写日志文件,每当日志文件写到一定大小时,比如是1G,会将这个日志文件改名成另一个名字,并新建一个与原文件名相同的日志文件,再往这个新建的日志文件里写数据;要求写一个程序能实时地读取日志文件中的内容,并且不能影响写操作与重命名操作。

首先,这个问题在windows下几乎无解,因为一个程序打开了一个文件,再要对文件重命名是不可能的;而在Linux下,可以得到完美解决。因为Linux的文件系统有别于windows,Linux不使用文件名,而是使用inode号码来识别文件。关于inode的详细介绍参看理解inode。


更新:在windows下实时读取也是可行的

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 blocke.printStackTrace();}try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();}try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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. java读取日志文件_Java实时读取日志文件

    RandomAccessFile类中seek方法可以从指定位置读取文件,可以用来实现文件实时读取. 一.实现步骤: 1.首先,要有服务器上日志文件的路径. String url="/logp ...

  2. java读取日志_Java实时监控日志文件并输出的方法详解

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

  3. java解析日志数据_Java实时监控日志文件并输出的方法详解

    Java实时监控日志文件并输出的方法详解 想在前台显示数据同步过程中产生的日志文件,在网上找到解决方案,做了代码测试好用.这里做个记录 java.io.RandomAccessFile可以解决同时向文 ...

  4. Linux实时监控日志文件的swatchdog

    1. 前言 本教程主要讲解在Linux系统中如何使用swatchdog实时监控日志文件的变化. swatchdog(Simple WATCH DOG)是一个简单的Perl脚本,用于监视类Unix系统( ...

  5. tail命令,实时查看日志文件

    一.前言 Linux 实时查看日志文件,最主要使用的就是tail命令. linux tail命令用于显示文件尾部的内容,默认在屏幕上显示指定文件的末尾10行.如果给定的文件不止一个,则在显示的每个文件 ...

  6. linux 暂停实时日志,Linux 实时查看日志文件动态内容

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

  7. Java项目中读取properties文件,以及六种获取路径的方法

    下面1-4的内容是网上收集的相关知识,总结来说,就是如下几个知识点: 最常用读取properties文件的方法 InputStream in = getClass().getResourceAsStr ...

  8. 安装补丁出现0xC8000222错误和系统日志中wuaueng.dll SUS20ClientDataStore 无法读取日志文件的错误...

    使用金山卫士为系统打补丁的时候,发现有很多补丁都被忽略了,当时我就觉得奇怪.昨天在偶然的机会里,查看Windows应用程序日志中的记录时(右击我的电脑,选择"管理",找到系统工具- ...

  9. 基于Java线程池读取数据库中数据(学习+运用)

    基于Java线程池读取数据库中数据(学习+运用) 以下是学习内容 Main.java import java.util.concurrent.ArrayBlockingQueue; import ja ...

最新文章

  1. 阿里异地多活与同城双活的架构演进
  2. 富文本编辑器的配置使用
  3. Spring MVC RedirectAttributes的用法解决办法
  4. mesos-master启动失败,报错Failed to load unknown flag 'quorum.rpmsave'
  5. JavaScript 字符串转数字
  6. 国科金:共融机器人基础理论与关键技术研究重大研究计划
  7. 文本挖掘预处理之TF-IDF
  8. 工业大数据发展面临四方面挑战
  9. 台式计算机安装无线网卡驱动程序,台式电脑无线网卡驱动程序怎么安装
  10. 我的世界java1.16.3村庄种子,我的世界基岩版1.16种子
  11. 人工智能革命:人类永生还是灭亡(下)
  12. 游戏翻译,本地化翻译如何做效果好
  13. linux 电脑观看电视,使用Zattoo在您的Ubuntu桌面上观看直播电视
  14. Expanding Cards
  15. 固定资产管理流程和技巧
  16. Oracle数据库——限定查询,范围查询,NULL判断-02
  17. Java实现监督学习在Aliens游戏中的探究尝试
  18. 将网页制作成chm文件
  19. 深入浅出CChart 每日一课——快乐高四第四十一课 投石问路,SoUI探险第一关之弹出窗口
  20. 【AI数学】相机成像之外参数

热门文章

  1. linux第五周微职位
  2. JAXB:Java对象序和XML互相转化的利器
  3. Windows下提升进程权限(转)
  4. ZH奶酪:Python中zip函数的使用方法
  5. 微软公有云魅力之Traffic Manager
  6. apache自定义虚拟主机日志格式
  7. 分析数十年的ICS利用,确定漏洞修复优先级
  8. RepBaseRepeatMaskerEdition下载 | RepeatMasker
  9. 《云服务器》与《传统服务器》的区别
  10. linux内存管理之malloc