2013-02-07 47 views
2

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

我目前正在使用它,但似乎有一个异常,我不能解释。基本上,我创建了一个名为FileMonitor的类,该类具有一个可触发的计时器,该计时器遍历一系列寻找已更改的“上次修改日期”的唯一文件。

一旦找到它,就会遍历一个Listeners列表来查找匹配的文件,并且它会通知到 fileChanged事件。然后它开始处理文件中添加的行。

因此,为了使我的问题更简洁:

  1. 是否Observer模式适合什么,我试图做的? (目前 我有一个Listener每个文件)
  2. 鉴于有多个文件到 显示器是否有任何'并发性问题'的可能性?

感谢

回答

4

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

从官方文档:

FileAlterationObserver代表文件的下方的根目录 的状态,检查文件系统和通知创建的听众, 更改或删除事件。

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

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

你必须注册oberver(S)与FileAlterationMonitor。从相同的文档继续:

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

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

在库中查找包中的程序包名为org.apache.commons.io.monitor

3

的Java 7已经推出WatchService该手表已注册的对象更改和事件。

通过调用其注册方法 ,返回一个WatchKey来表示注册,一个可监视对象向watch服务注册。 当检测到对象的事件时,密钥会发出信号,并且如果 当前没有发送信号,它会排队等待监视服务,以便其可以调用轮询或使用方法 检索密钥和进程的消费者可以检索它 事件。一旦处理完事件 ,消费者调用密钥的重置方法来重置钥匙,钥匙可以通过其他事件发出信号并重新排队。

文件系统可能会报告事件的速度超过它们可以检索或处理的数量,并且实施可能会对可能累积的事件数量施加未指定的限制。在执行 故意丢弃事件的情况下,它将安排密钥的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<WatchEvent<?>> 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()); 
    } 
} 

参考 - link

+0

谢谢 - 但遗憾的是我使用Java 6 *,因为我们现有的技术都在6 * –

+0

上,您可以使用[Apache VFS](http://commons.apache.org/vfs/)究竟是什么与java相同6. –

2

是否Observer模式适合什么,我试图做的?(目前我 每个文件有一个Listener)

是的。

是否有任何'并发性问题'的可能性,因为有 多个文件来监视?

如果你有多个线程删除和添加听众通过在运行的ConcurrentModificationException风险的ArrayList备份列表。改为使用CopyOnWriteArrayList

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

+0

+1因为a。正确和b。这个问题的答案没有增加另一个依赖。 – Hannes