从Java中不断更新的文件中读取新数据
我有一个日志文件,它不断更新新的数据行。我需要在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
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键盘集成,这是从中获取信息的唯一方法(显然不会侵入内存)是通过读取它的日志文件,这些文件会在游戏中发生事件时立即更新。