实现一个等价于tail -f somefile
的java文件观察器
我读过一些类似的问题。我看到了一些选择。
-
使用
BufferedReader
,基本思想是使用缓冲读取器从文件中读取。如果返回null,则休眠几秒钟,然后在无限循环中继续。我对此进行了一些实验,结果显示,只要你读到文件的末尾,getLine
方法就不会再给你任何更新。那么这种方法有效吗? -
使用CCD_ 4。每次进行读取操作时,创建一个随机访问文件,并将文件长度与历史文件长度进行比较,如果当前文件长度较长,则在delta部分查找最后一次读取。我确信这是有效的,但每次读取时都会打开一个新的随机访问文件,难道没有更有效的方法吗?
-
我看到新的JDK将
stream
API添加到缓冲文件读取器中,我想这与尾部附加的新内容无关。它只与最初给出的内容有关。我的问题是,这个流api是否可以扩展为考虑tailer function
?
问题:
-
BufferedReader
可以用于实现tail -f
吗?在我的情况下,一旦我读取passEOF,只返回null。 -
JDK8
stream
能否用于实现tail -f
? -
除了像apachecommonlib这样反复打开关闭文件之外,还有更有效的实现吗?
我最终使用了一些Apache库来修复这个问题。(我记住后会更新)。
本质上,文件观察者是依赖于文件系统API的。在linux发行版上,通过EOF进行读取可能会很好,并带来稍后附加的新内容。
我观察到的问题是在MACO上,一旦您在EOF之后读取到该文件处理程序就不再有效。如果您知道正在读取新内容,则必须重新打开该文件。
- 这是在MacOs Maveriks上,我没有测试它在最新版本上仍然是一样的
- 这也是基于JDKAPI,而不是底层的MACOS文件系统api。因为我觉得CCD_ 11 CCD_
我不久前就这么做了,根据我的经验,我想你的问题可能没有意义——最好在两次读取之间关闭文件,或者像我的类似问题中建议的那样使用Apache Tailer类
我怎样才能按照";尾部-f";在Java中执行而不打开文件(防止重命名/删除)
这不仅有帮助,因为它可以帮助你刷新,而且可以在你阅读文件时防止文件被锁定
我最终没有使用它(因为在我的环境中获得软件批准很有挑战性)——相反,我选择使用这样的过程:
Detect Change
Open file
Seek to previous position
Read to end of file
Remember position for next seek
Close
这个预成型件非常好,解决了很多问题——我已经用了一段时间了。
有人建议使用java.nio.file.WatchService.poll()来检测有效的更改,但重复读取文件大小也是如此。
您在#2中提到了这种打开/寻找/关闭方法——不要担心性能,因为与等待文件更新相比,打开/尾部/关闭部分的时间非常短。如果希望提高效率,请在文件大小测试之间增加更长的延迟。这样一来,它一次会分块出更多的行,但读取文件的频率会降低。
回顾我的代码,我最终使用了一个FileChannel(FileInputStream.getChannel()),它有一个位置设置方法。