读取翻转的日志文件

时间:2013-05-15 06:12:18

标签: java randomaccessfile

我正在尝试使用一个简单的程序来读取日志文件。使用的代码如下:

RandomAccessFile in = new RandomAccessFile("/home/hduser/Documents/Sample.txt", "r");
String line;
while(true) {
if((line = in.readLine()) != null) {
System.out.println(line);
} else {
Thread.sleep(2000); 

该代码适用于添加到日志文件的新行,但它不会复制翻转过程。即当清除日志文件的内容时,我希望java控制台继续从新写入日志的第一行读取文本。这有可能吗?需要对现有代码进行哪些更改才能实现?

3 个答案:

答案 0 :(得分:1)

在我的工作中,我不得不处理可以翻转的日志,而不会遗漏任何数据。我所做的是存储一个包含以下内容的小备忘录文件:

  • 日志的前1024个字节(或更少)的哈希值(我使用SHA-1或其他东西,因为它很容易)
  • 用于生成哈希的字节数
  • 当前档案位置

在处理完所有行或一些最大行数后关闭日志文件,并更新备忘录文件。我睡了一会儿,然后再次打开日志文件。这允许我检查是否发生了翻转。在以下情况下检测到翻转:

  1. 当前文件小于上一个文件位置
  2. 哈希值不一样
  3. 在我的情况下,我可以使用哈希来查找正确的日志文件,并向后工作以获取最新信息。一旦我知道我已经在正确的文件中找到了我离开的地方,我可以继续阅读并记住我的位置。我不知道这是否与你想做的事情有关,但也许这会给你一些想法。

    如果您没有任何持久性要求,则可能不需要存储任何备忘录文件。如果你的'翻转'只是清除日志并且不移动它,你可能不需要记住任何文件哈希值。

答案 1 :(得分:0)

I am sorry... My Bad.. I don't want it to go blank.. I just want the next new line written to the log to be read.

由于您需要能够在清除文件时从头开始读取,因此您需要监视文件的长度并在文件长度减少时重置光标指针。您可以使用seek(..)方法重置光标。

见下面的代码 -

RandomAccessFile in = new RandomAccessFile("/home/hduser/Documents/Sample.txt", "r");
String line;
long length = 0;//used to check the file length
while (true) {
    if(in.length()<length){//new condition to reset position if file length is reduced 
        in.seek(0);
    }
    if ((line = in.readLine()) != null) {
        System.out.println(line);
        length = in.length();
    } else {
        Thread.sleep(2000);
    }
}

答案 2 :(得分:0)

<块引用>

它不会复制翻转过程。即当日志文件的内容被清除时,我希望 java 控制台继续从新写入日志的第一行读取文本。这可能吗?

也在为此苦苦挣扎。 +1 给@paddy 的哈希想法。

另一种解决方案(取决于您的操作系统)是使用文件的 inode,尽管这可能仅适用于 unix:

Long inode = (Long)Files.getAttribute(logFile.toPath(), "unix:ino");

这将返回与日志文件关联的底层文件系统的 inode。如果 inode 发生更改,则该文件是一个全新的文件。这假设当日志被翻转时,它被移到一边并且相同的文件没有被覆盖。

为了完成这项工作,您需要记录您正在读取的文件的 inode,然后如果您在一段时间内没有获得任何新数据,请检查该 inode 是否已更改。