从Java中不断更新的文件中读取新数据

从Java中不断更新的文件中读取新数据,java,io,file-read,Java,Io,File Read,我有一个日志文件,它不断更新新的数据行。我需要在java中获得新添加的数据。目前,我的解决方案是: public static void readNonStop(String filename, boolean goToEnd, FileReadCallback readCallback) { if(readCallback == null) { return; } try { BufferedReader br = new Buffere

我有一个日志文件,它不断更新新的数据行。我需要在java中获得新添加的数据。目前,我的解决方案是:

public static void readNonStop(String filename, boolean goToEnd, FileReadCallback readCallback) {
    if(readCallback == null) {
        return;
    }
    try {
        BufferedReader br = new BufferedReader(new FileReader(filename));
        try {
            String line = br.readLine();
            int lineNumber = 0;

            if(goToEnd) {
                while(br.readLine() != null) {}
            }

            while (true) {
                if(line != null) {
                    readCallback.onRead(lineNumber++, line);
                } else {
                    Thread.sleep(1);
                }
                line = br.readLine();
            }
        } finally {
            br.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
但我有一种感觉,应该有更好的方法。我不喜欢内部带有“sleep”的常量runnin循环,我更喜欢某种事件驱动的方法

如果每次修改文件时都依赖文件系统事件重新打开文件,则会产生延迟

在这种情况下,正确的做法是什么


提前谢谢

文件不是设计为消息传递解决方案的。即使在环回上使用TCP,也可能有10-30微秒的延迟。如果不更改文件格式,您的解决方案可能是最快的

注意:你不必睡整整一毫秒。您可以使用
Thread.yield()
LockSupport.parknos(100_000)
对于更复杂的策略,您可以有一个类似的类,它以可配置的方式后退

顺便说一句,我实现了一个以低延迟方式写入/读取文件的解决方案,称为“编年史队列”。这有亚微秒的延迟使用二进制格式的速度


注意:当您以FileInputStream打开文件时,可以跳过所有可用的字节(),直到结束。这可能会导致行不完整,具体取决于缓冲的工作方式。

目前,您没有具体的问题。因此,您的帖子更适合您查看Java Watch服务。这比尝试实现自己的逻辑要好。看看这篇文章——我目前正在使用WatchService,但问题是,这会导致延迟,因为您需要一直打开和关闭文件。尽快需要数据。您是否尝试过apache commons TailerListener?Javadoc:实现:感谢您的回答。目前,我唯一不喜欢这个解决方案的地方是,如果没有“Thread.sleep”,CPU会承受很大的压力。如果睡眠时间至少为1毫秒,CPU使用率将从40%降至0-1%。在某些情况下,使用WatchService会导致长达5-6秒的延迟,这是不可接受的。问题是,这是获取所需信息的唯一途径,因此我无法切换通信方式。不过我应该改用FileInputStream。你可能会发现睡眠时间超过10毫秒是可以的。LongPauser所做的是睡眠时间越来越长,直到调用reset()。在代码审查时,我得到了一个使用ApacheCommons类的建议。看看代码,看起来我的想法是对的。虽然更健壮一些,
Tailer
使用与我的代码相同的逻辑,但它在循环中读取线程。sleepdelay。文件不是设计为消息传递解决方案的。的确这是一个非常糟糕的设计-尤其是如果Java是使用的工具。读取一个不断变化/增长的文件非常困难,因此使用低级C代码是非常可靠的。使用Java实际上是不可能的,因为您无法控制JVM是否缓存文件大小,例如。@AndrewHenle,我正在为游戏编写RGB键盘集成,这是从中获取信息的唯一方法(显然不会侵入内存)是通过读取它的日志文件,这些文件会在游戏中发生事件时立即更新。