2017-02-28 96 views
0

對於我當前的項目,我需要使用WatchService來跟蹤給定目錄中的事件。我的代碼還主要是基於關閉的Oracles WatchService tutorial example使用WatchService忽略文件事件(創建,修改,刪除)

然而,我需要它僅限於文件夾唯一事件(例如ENTRY_CREATE C:\ TEMP \ folder_a)。

我試圖做的是把目錄的內容 的初始快照,以及每個內容的路徑存儲到任何dirCachefileCache

如果一個新的事件被註冊這應該被檢查:

  • 是事件上下文中文件fileCache
  • 是事件上下文的新文件( - > Files.i sRegularFile)

因此,這兩個新的文件事件都應該被丟棄或者已經存在於緩存中的文件中的事件。

但印刷出來的事件產生

ENTRY_DELETE:C:\ TEMP \ k.txt

的文件,但沒有ENTRY_CREATE或ENTRY_MODIFY。

我在做什麼錯?我沒有正確檢查緩存嗎?還是完全不同的東西?

下面是當前代碼庫:

public class Main { 
    public static void main(String[] args) { 
     try { 
      new DirectoryWatcher(Paths.get("C:\\temp")).processEvents(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

DirectoryWatcher

package service; 

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; 
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; 
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; 
import static java.nio.file.StandardWatchEventKinds.OVERFLOW; 

import java.io.IOException; 
import java.nio.file.FileSystems; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.WatchEvent; 
import java.nio.file.WatchEvent.Kind; 
import java.nio.file.WatchKey; 
import java.nio.file.WatchService; 
import java.util.HashMap; 
import java.util.Map; 

/** 
* Slightly modified version of Oracle 
* example file WatchDir.java 
*/

public class DirectoryWatcher { 
    private final Path path; 
    private final WatchService watcher; 
    private final Map<WatchKey,Path> keys; 
    private PathSnapshot pathSnapshot; 
    private boolean trace = false; 

@SuppressWarnings("unchecked") 
static <T> WatchEvent<T> cast(WatchEvent<?> event) { 
    return (WatchEvent<T>)event; 
} 

/** 
* Register the given directory with the WatchService 
*/ 
private void register(Path dir) throws IOException { 
    WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); 
    if (trace) { 
     Path prev = keys.get(key); 
     if (prev == null) { 
      System.out.format("register: %s\n", dir); 
     } else { 
      if (!dir.equals(prev)) { 
       System.out.format("update: %s -> %s\n", prev, dir); 
      } 
     } 
    } 
    keys.put(key, dir); 
} 

public DirectoryWatcher(Path dir) throws IOException { 
    this.watcher = FileSystems.getDefault().newWatchService(); 
    this.keys = new HashMap<WatchKey,Path>(); 
    this.path = dir; 
    this.pathSnapshot = new PathSnapshot(dir); 

    register(dir); 
    // enable trace after initial registration 
    this.trace = true; 
} 

/** 
* Process all events for keys queued to the watcher 
*/ 
void processEvents() { 
    for (;;) { 

     // wait for key to be signaled 
     WatchKey key; 
     try { 
      key = watcher.take(); 
     } catch (InterruptedException x) { 
      return; 
     } 

     Path dir = keys.get(key); 
     if (dir == null) { 
      System.err.println("WatchKey not recognized!!"); 
      continue; 
     } 

     for (WatchEvent<?> event: key.pollEvents()) { 
      Kind<?> kind = event.kind(); 

      // TBD - provide example of how OVERFLOW event is handled 
      if (kind == OVERFLOW) { 
       continue; 
      } 

      // Context for directory entry event is the file name of entry 
      WatchEvent<Path> ev = cast(event); 
      Path name = ev.context(); 
      Path child = dir.resolve(name); 
      this.updateDirContent(); 
      /* 
      * currently: creating file events are neglected 
      * but deleting a file creates an event which is printed 
      * TODO: disregard delete event if sent from file 
      */ 
      boolean isFile = Files.isRegularFile(child); 
      if (pathSnapshot.isInFileCache(child)|| isFile) { 
       //disregard the event if file 
       event = null; 
      } else { 
       // print out event 
       System.out.format("%s: %s\n", event.kind().name(), child); 
      } 
     } 

     // reset key and remove from set if directory no longer accessible 
     boolean valid = key.reset(); 
     if (!valid) { 
      keys.remove(key); 
      // all directories are inaccessible 
      if (keys.isEmpty()) { 
       break; 
      } 
     } 
    } 
} 

private void updateDirContent() { 
    this.pathSnapshot = pathSnapshot.updateSnapshot(path); 

} 
} 

PathSnapshot

package service; 

import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.util.ArrayList; 
import java.util.stream.Stream; 

public class PathSnapshot { 
    public ArrayList<Path> dirCache = new ArrayList<Path>(); 
    public ArrayList<Path> fileCache = new ArrayList<Path>(); 

    public PathSnapshot(Path dir) { 
     try { 
      Stream<Path> rawDirContent = Files.walk(
        dir, 1); 

      Object[] dirContent = rawDirContent.toArray(); 
      rawDirContent.close(); 

      sortIntoCache(dirContent, dir); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void sortIntoCache(Object[] dirContent, Path rootdir) { 
     for (Object object : dirContent) { 
      //create path from element 
      Path objectPath = Paths.get(object.toString()); 
      //skip start path/the root directory 
      if (object.equals(rootdir)) { 
       continue; 
      } else if (Files.isRegularFile(objectPath)) { 
       fileCache.add(objectPath); 
      } else if (Files.isDirectory(objectPath)) { 
       dirCache.add(objectPath); 
      } 
     } 
    } 

    public boolean isInFileCache(Path path) { 
     if (fileCache.contains(path)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public boolean isInDirCache(Path path) { 
     if (dirCache.contains(path)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public PathSnapshot updateSnapshot(Path dir){ 
     return new PathSnapshot(dir); 
    } 
} 

回答

0

您現在收聽的所有可能的前夕從文件系統nts,所以沒有更多的要求。如果操作系統不提供更多的事件和更詳細的信息,Java就無能爲力。一些複雜的文件系統操作不是由一個事件代表,而是由一系列基本事件代表。所以你必須充分利用這些事件,並且必須解釋一系列事件實際上意味着什麼。

+0

但是,不應該我自己的實施工作嗎?如果創建了一個文件,我更新* PathSnapshot *,並且如果發生刪除事件,則上下文將類似於「C:\ temp \ a_file.txt」,如果這是針對fileCache進行檢查的,則將其註冊爲文件事件並將其丟棄。 –

相關問題