2013-02-07 43 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