实时读取日志文件

需求:在生成日志文件的过程中,需要实时读取该日志,需要每次读取时记录一次读取的位置,下一次从该位置读取

参考:http://sunnylocus.iteye.com/blog/694666

问题:由于我是每次读取几十行日志就停止一次,如果使用上面连接的代码RandomAccessFile.length()记录文件位置,发现记录的位置远大于读取的位置,这样为导致丢失一部分信息

方法1:因为日志是一直在写,一开始从0开始,可以先记录一下当前读取位置的的指针,下一次开始读的时候从该处再次读取

方法1需要用到以下内容:

randomAccessFile.getFilePointer()

此方法返回从文件开始的偏移量,以字节为单位,当前位置的偏移量

randomAccessFile.readLine()

方法从这个文件读取文本的下一行。该方法依次从文件中读取的字节处开始,从当前文件指针,直到它到达一个行结束或在文件的结尾。每个字节是通过采取字节的值的低8位的字符,并设置高8位字符的零转换成一个字符。

RandomAccessFile.seek()

偏移位置,以字节为单位从文件的开头计量,在其上设置文件指针。

RandomAccessFile.length()

此方法返回当前文件的长度,以字节为单位。

File logFile = new File("D:\\workspace\\drawChart\\src\\read_log\\log.txt");
   private long lastTimeFileSize = 0; // 上次文件大小

 protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
        //获取保存的上一次读取的位置
        String str = request.getParameter("lastTimeFileSize");
        lastTimeFileSize = Long.parseLong(str);
        System.out.println(lastTimeFileSize);          

        try {
            long len = logFile.length();
            System.out.println(len);
            if(lastTimeFileSize >= len){
                lastTimeFileSize = len;
                try {
                    //如果读取的速度超过写的速度,等待5秒
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }else{
                 RandomAccessFile randomFile = new RandomAccessFile(logFile, "r");
                 randomFile.seek(lastTimeFileSize);
                 String tmp = null;
                 while ((tmp = randomFile.readLine()) != null) {                                                                                           if(matcher0.lookingAt()){
                         if(flag==4){
                            //记录读取文件的位置
                            lastTimeFileSize = randomFile.getFilePointer();
                            System.out.println(lastTimeFileSize);
                            //保存指针
                         }
                     }

        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //其它操作
        }
    }  

方法2:记录行号

    --如果用循环读取方法,循环会消耗资源,使系统负担太重

原文地址:https://www.cnblogs.com/zhxuxu/p/9745730.html

时间: 2024-10-11 03:21:08

实时读取日志文件的相关文章

python 实时遍历日志文件

open 遍历一个大日志文件 使用 readlines() 还是 readline() ? 总体上 readlines() 不慢于python 一次次调用 readline(),因为前者的循环在C语言层面,而使用readline() 的循环是在Python语言层面. 但是 readlines() 会一次性把全部数据读到内存中,内存占用率会过高,readline() 每次只读一行,对于读取 大文件, 需要做出取舍. 如果不需要使用 seek() 定位偏移, for line in open('fi

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

配置hadoop环境 配置flume环境 配置flume文件 D:\Soft\apache-flume-1.8.0-bin\conf 将 flume-conf.properties.template 重新命名为  hdfs.properties # 组装 agenta1.sources = s1a1.channels = c1a1.sinks = k1 # 配置source:从目录中读取文件a1.sources.s1.type = spooldira1.sources.s1.channels =

读取日志文件,并判断IP次数>200的加入黑名单

import timepoint=0 #第一次开始读取时从0开始while True: #服务器一直再运行所以写个死循环 ips={}#定义一个空字典存放IP用,放在循环下边是因为每次读取时都会重新定义 f = open('access.log',encoding='utf-8') f.seek(point)#每次读取时的开始位置 for line in f.readlines():#获取到所有内容,每条进行循环 ip=line.split()[0] #按照空格分隔,取到第一个元素ip if i

读取日志文件,搜索关键字,打印关键字前5行。yield、deque实例

from collections import deque def search(lines, pattern, history=5): previous_lines = deque(maxlen=history) for line in lines: if pattern in line: yield line,previous_lines previous_lines.append(line) if __name__ == '__main__': with open('log.txt','r

mysql 的日志文件

mysql的日志文件 日志文件大致分为  error log, binary log, query log, slow query log, innodb redo log ;如图: 1.error log the error log file contains information indicating when mysqld was started and stopped also any critical errors that occur while the server is run

遍历日志文件并打印

<?phperror_reporting(E_ALL);ini_set('display_errors', 1); function load($file){ //No.1 //开始写代码,读取日志文件 $file = fopen($file,'r'); $contents = array(); while(!feof($file)) { $contents[] = fgets($file); } return $contents;} function eliminate($lines){ $n

[PHP] 读取大文件并显示

使用PHP读取日志文件,当文件比较大的时候,会报内存不足,因此应该部分读取,读取指定的行数的数据 PHP代码: <?php class Test{ //日志路径 const LOG_PATH="E:\phpServer\Apache\logs\error.log"; const NGINX_LOG_PATH="E:\phpServer\\nginx\logs\error.log"; //显示的行数 const PAGES=50; public static f

关于日志文件的一些处理

一. 一个日志文件,行的信息中包括调用的接口名,如何找出日志文件中访问量在前10位的接口. apis = [] # 定义空列表用于存放从日志行中取出的接口名with open('Log.txt') as fr: # 以行读取日志文件,并在行中截取出接口名存放至apis列表中 for line in fr: api = line.split(' ')[4] apis.append(api)api_set = list(set(apis)) # 为了在统计每个接口名个数时减少循环次数,把接口名列表做

基于c++的日志文件实现

概述 所有的商业软件或线上系统都具有日志功能,因为日志信息提供了系统启动以来的重要的操作或状态迁移记录,是追踪各种异常错误的第一手资料.绝大部分系统的日志模块会自动保留历史日志文件,即:日志文件大小达到约定上限时,自动转储到一个新的历史文件,当前文件清空并继续记录新的日志信息,例如:假设当前日志文件名为test.log, 当它的大小到达上限(例如10MB)时,就把其文件内容转储到新文件test.log.1, 然后test.log清空并继续记录新信息.根据配置不同,我们可以保留1到N份历史日志文件