观察者模式适合文件监控?

我很想知道观察者模式是否是实现代码来监视日志文件及其更改的正确方法?

我目前正在使用它,但似乎有一个我无法解释的exception现象。 基本上,我创建了一个名为FileMonitor的类,它有一个触发的计时器,它迭代一个独特文件列表,寻找一个改变的“最后修改日期”。

在找到它之后,迭代监听器列表以找到匹配的文件,并通知它的fileChanged事件。 然后它开始处理文件中添加的行。

所以让我的问题更简洁:

  1. 观察者模式是否适合我想要做的事情? (目前我每个文件有一个监听器)
  2. 考虑到要监控多个文件,是否存在“并发问题”的可能性?

谢谢

如果您不想使用Java 7,则可以使用Apache IO获得相同的行为。

从官方文档:

FileAlterationObserver表示根目录下的文件状态,检查文件系统并通知侦听器创建,更改或删除事件。

以下是如何添加侦听器以定义在发生此类事件时要执行的操作。

File directory = new File(new File("."), "src"); FileAlterationObserver observer = new FileAlterationObserver(directory); observer.addListener(...); observer.addListener(...); 

您必须使用FileAlterationMonitor注册FileAlterationMonitor 。 继续使用相同的文档:

  long interval = ... FileAlterationMonitor monitor = new FileAlterationMonitor(interval); monitor.addObserver(observer); monitor.start(); ... monitor.stop(); 

其中interval是在检查文件系统之间等待的时间量(以毫秒为单位)。

在库中查找名为org.apache.commons.io.monitor包。

Java 7引入了WatchService ,它WatchService注册对象的变化和事件。

Watchable对象通过调用其register方法向watch服务注册,返回WatchKey来表示注册。 当检测到对象的事件时,发信号通知密钥,如果当前没有信号通知,则将其排队到监视服务,以便调用该轮询的消费者可以检索该密钥,或者采取方法来检索密钥和处理事件。 一旦处理了事件,消费者就会调用密钥的重置方法来重置密钥,该密钥允许密钥发出信号并与其他事件一起重新排队。

文件系统可以比检索或处理事件更快地报告事件,并且实现可以对其可能累积的事件的数量施加未指定的限制。 如果实现有意丢弃事件,则它会安排密钥的pollEvents方法返回事件类型为OVERFLOW的元素。 消费者可以将此事件用作重新检查对象状态的触发器。

示例 –

 Path myDir = Paths.get("D:/test"); try { WatchService watcher = myDir.getFileSystem().newWatchService(); myDir.register(watcher, StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY); WatchKey watckKey = watcher.take(); List> events = watckKey.pollEvents(); for (WatchEvent event : events) { if (event.kind() == StandardWatchEventKind.ENTRY_CREATE) { System.out.println("Created: " + event.context().toString()); } if (event.kind() == StandardWatchEventKind.ENTRY_DELETE) { System.out.println("Delete: " + event.context().toString()); } if (event.kind() == StandardWatchEventKind.ENTRY_MODIFY) { System.out.println("Modify: " + event.context().toString()); } } } catch (Exception e) { System.out.println("Error: " + e.toString()); } } 

参考 – 链接

观察者模式是否适合我想要做的事情? (目前我每个文件有一个监听器)

是的,它确实。

考虑到要监控多个文件,是否存在“并发问题”的可能性?

如果您有多个线程删除并将侦听器添加到由ArrayList备份的列表,则存在ConcurrentModificationException的风险。 请改用CopyOnWriteArrayList

IIRC有效的java有一篇文章,其中包含一个很好的例子。

我建议去找NIO

和文件观察程序服务 – 查看文件以进行更改