Java实时读取日志文件

3
我正在用Java编写一个Cod4服务器控制器(我知道有完全合适的服务器控制器,但我想从中学习)。现在,我想根据日志文件中的条目采取特定操作,这个文件由Cod经常更新,而且文件可能会变得非常大。那么,如何高效地仅读取文件中已更改的部分,每秒钟一次?
或者有没有一种方法可以将日志文件中所有更改的内容实时发送到Java?(我读到了关于管道的东西)。服务器运行在Linux上。不需要将日志文件仍保存在相同的位置,因为所有内容都应通过Java进行保存。
接受大约1或2秒的延迟,但不能再长了。
3个回答

2

类似这样的命令' tail -f logfile.txt > java -jar test.jar '也能起作用吗? - teuneboon
当然,那么你可以从stdin读取。您是否曾经直接从终端输入日志记录?您的程序的主要输入是日志文件条目吗?附言:您需要一个管道|而不是>。 - rohannes
确实使用了管道,它非常有效,谢谢 :) - teuneboon

2

当您阅读日志文件时,如果没有更多的条目,您可以暂停,并稍后继续处理。该过程将在文件被写入时继续运行,仅读取附加到末尾的额外行。

BufferedReader br = ...;
String line = null;
while (true) {
  line = br.readLine();
  if (line == null) // nothing more to read, wait... 
  {
    Thread.sleep(delay);
  } else {
    process(line); // take action
  }
}

注意:如果文件已关闭并滚动,则此方法可能无法正常工作,您需要采取更高级的方法来处理。

这也是一个有效的解决方案,但我觉得rohannes的解决方案更加优雅。不过如果由于某些原因它不能正常工作,我可能会使用这个 :)。 - teuneboon

0
你可以使用 RandomAccessFile。你可以像这样存储指向你已读取的最后一个字节的指针:
String pathToYourFile = "/path/to/your/logfile";
long lastBytePosition = 0;
boolean shouldStop = false;
while (! shouldStop) {
    Thread.sleep(2000);
    File f = new File(pathToYourFile);
    long length = f.length();
    RandomAccessFile raf = new RandomAccessFile(f, "r");
    byte[] buff = new byte[(int) (length - lastBytePosition)];
    raf.readFully(buff, (int) lastBytePosition, (int) (length - lastBytePosition));
    shouldStop = processChunk(buff);
    lastBytePosition = (int) length;
}

...其中processChunk是处理来自文件的新输入的方法。

虽然离完美还有很远的距离,但我认为你已经理解了这个概念。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接