我想从我的java应用程序中读取syslog
条消息。我将查看文件/var/log/messages
。
那个文件可能很大。我想有一个主题:
实现步骤1的最佳(有效)方法是什么?如何从文件中不断读取新行?
答案 0 :(得分:0)
首次尝试检查更改时,启动线程并获取文件的实例。这将是你的出发点。现在使用 Java Diff Utility 检查您的文件是否附加了新行或者文件中发生的任何类型的更改。
让我们调用文件currentFile
您可以使用此实用程序继续检查新数据。
https://code.google.com/p/java-diff-utils/
Diff Utils库是一个OpenSource库,用于执行文本之间的比较操作:计算差异,应用补丁,生成统一差异或解析它们,生成差异输出以便于将来显示(如并排视图)等等
以下是检查更改的示例代码
import difflib.*;
public class BasicJavaApp_Task1 {
// Helper method for get the file content
private static List<String> fileToLines(String filename) {
List<String> lines = new LinkedList<String>();
String line = "";
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
while ((line = in.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return lines;
}
public static void main(String[] args) {
List<String> original = fileToLines("originalFile.txt");
List<String> revised = fileToLines("revisedFile.txt");
// Compute diff. Get the Patch object. Patch is the container for computed deltas.
Patch patch = DiffUtils.diff(original, revised);
for (Delta delta: patch.getDeltas()) {
System.out.println(delta);
}
}
}
您可以使用Delta
检查您要查找的特定数据。
现在由您来决定您希望比较发生的频率是多少。像每1000毫秒,或10000毫秒等。
另外,请确保每次比较后都应更新currentFile
对于第2步:发送回叫您可以执行以下操作
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
void registerCallback() {
ses.schedule(new MyCommand(), 30, TimeUnit.SECONDS);
}
它会返回Future
,如果您愿意,可以用来取消执行,或者获取MyCommand返回的值。
如果您想安排一个能够及时重复的命令,您可以使用其他调度方法:scheduleAtFixedRate
和scheduleWithFixedDelay
。
如果您只需要在某种条件下重新安排,或者以不同的速率或间隔重新安排,我使用的一种技术是将ScheduledExecutorService
传递给您的命令(即new MyCommand(ses))
并让其重新安排本身或具有适当延迟的新命令:
class MyCommand implements Runnable {
private final ScheduledExecutorService ses;
MyCommand(ScheduledExecutorService ses) { this.ses = ses; }
private boolean shouldReschedule() { ... }
private int getRescheduleTimeoutMs() { ... }
@Override void run() {
// do work
...
// reschedule if needed
if (shouldReschedule()) {
// reschedule this command:
ses.schedule(this, getRescheduleTimeoutMs(), TimeUnit.MILLISECONDS);
// or else a new one:
ses.schedule(new MyCommand(ses), ...);
}
}
}