从 Java 中不断更新的文件中读取新数据
Reading new data from a constantly updating file in Java
我有一个日志文件,它会不断更新新的数据行。我需要在写入后立即在 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" 的恒定运行循环的想法,我更喜欢某种事件驱动的方法。
如果我依赖文件系统事件在每次修改文件时重新打开文件,它会产生延迟。
对于这种情况,正确的做法是什么?
提前致谢!
文件不是为消息传递解决方案而设计的。即使使用 TCP over loopback 也会有 10 - 30 微秒的延迟。在不更改文件格式的情况下,您的解决方案可能是最快的。
注意:您不必休眠整整一毫秒。您可以使用 Thread.yield()
或 LockSupport.parkNanos(100_000);
对于更复杂的策略,您可以使用像 LongPauser 这样的 class 以可配置的方式回退。
顺便说一句,我以低延迟方式实现了 write/read 文件的解决方案,称为 Chronicle Queue。这具有亚微秒延迟,使用二进制格式来提高速度。
注意:当您将文件作为 FileInputStream 打开时,您可以通过跳过所有字节 available()
来结束。根据缓冲的工作方式,这可能会导致行不完整。
我有一个日志文件,它会不断更新新的数据行。我需要在写入后立即在 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" 的恒定运行循环的想法,我更喜欢某种事件驱动的方法。
如果我依赖文件系统事件在每次修改文件时重新打开文件,它会产生延迟。
对于这种情况,正确的做法是什么?
提前致谢!
文件不是为消息传递解决方案而设计的。即使使用 TCP over loopback 也会有 10 - 30 微秒的延迟。在不更改文件格式的情况下,您的解决方案可能是最快的。
注意:您不必休眠整整一毫秒。您可以使用 Thread.yield()
或 LockSupport.parkNanos(100_000);
对于更复杂的策略,您可以使用像 LongPauser 这样的 class 以可配置的方式回退。
顺便说一句,我以低延迟方式实现了 write/read 文件的解决方案,称为 Chronicle Queue。这具有亚微秒延迟,使用二进制格式来提高速度。
注意:当您将文件作为 FileInputStream 打开时,您可以通过跳过所有字节 available()
来结束。根据缓冲的工作方式,这可能会导致行不完整。