2016-12-30 185 views
-1

我有一個程序監視目錄中的任何更改。文件路徑對於java中的路徑對象不正確

這是程序的輸出。

C:\REST API\source\data_id.txt 

The new file :data_id.txtEvent :ENTRY_CREATE 

C:\REST API\source\New folder  

The new file :New folderEvent :ENTRY_CREATE 

C:\REST API\source\NhuPhutBanDau-NooPhuocThinh-4549467.doc 

The new file :NhuPhutBanDau-NooPhuocThinh-4549467.docEvent :ENTRY_CREATE 

我的程序監視根目錄C:/REST API/source的任何更改。當我將data_id.txt文件複製到根目錄時,它可以檢測到新文件,如上面的輸出和目錄中所示。

之後,當我嘗試創建一個文件夾時,它也能夠檢測到有一個新文件夾並在輸出中顯示新文件夾目錄。

但問題是,當我嘗試將文件放入新創建的文件夾時,它再次能夠檢測到新文件夾C:\REST API\source\New folder中的更改,該文件夾不是我的程序中設置的根目錄C:\REST API\source

我需要程序檢測只在根目錄中的更改。

有人可以指導我嗎?

這是我的源代碼:

public class fileStatus { 

    private final WatchService svc = null; 
    private final HashMap<WatchKey , Path> keyMap = null; 

    public static void main(String [] args) throws FileNotFoundException, IOException, JSONException, InterruptedException 
    { 
    try(WatchService svc = FileSystems.getDefault().newWatchService()) 
     { 
      Map<WatchKey, Path> keyMap = new HashMap<>(); 
      Path path = Paths.get("C:/REST API/source/"); 
      fileStatus fs = new fileStatus(); 
      fs.registerAll(path,keyMap,svc); 
      WatchKey wk ; 
      do 
      { 

       wk = svc.take(); 
       Path dir = keyMap.get(wk); 
       for(WatchEvent<?> event : wk.pollEvents()) 
       { 
        WatchEvent.Kind<?> type = event.kind(); 
        Path fileName = (Path)event.context(); 
        Path child = path.resolve(fileName); 
        System.out.println(child); 
        if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) 
        { 
         if(type == StandardWatchEventKinds.ENTRY_CREATE) 
         { 
          registerAll(child,keyMap,svc); 
         } 
        } 
        System.out.println("\nThe new file :"+fileName+ "Event :" +type); 
       } 
      }while(wk.reset()); 
     } 
    catch(IOException e) 
    { 
     e.printStackTrace(); 
    } 

    } 

    private static void registerAll(Path path, Map<WatchKey, Path> keyMap, WatchService svc) throws IOException 
    { 
     Files.walkFileTree(path,new SimpleFileVisitor<Path>() 
       { 
        public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) throws IOException 
        { 
         if(attrs.isDirectory()) 
         { 
          keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path); 
         } 
         return FileVisitResult.CONTINUE; 
        } 
       }); 

    } 

} 
+0

* Java編譯器*當然不會顯示該輸出。 *您的程序*是。 – Andreas

+0

問自己這個問題:keyMap的目的是什麼? – Andreas

+0

用於註冊觀察者服務和事件 – attack

回答

1

有一對夫婦的你在哪裏註冊的監控文件創建這是沒有必要的路徑的地方。

  1. 您可以從您main方法

      if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) { 
           if (type == StandardWatchEventKinds.ENTRY_CREATE) { 
            registerAll(child, keyMap, svc); 
           } 
          } 
    
  2. 刪除整個塊你不應該在registerAll方法做散步樹。因此,而不是這個,

    Files.walkFileTree(path,new SimpleFileVisitor<Path>() 
    { 
        public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) throws IOException 
        { 
         if(attrs.isDirectory()) 
         { 
          keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path); 
         } 
         return FileVisitResult.CONTINUE; 
        } 
    }); 
    

只要使用此:

keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path); 

上面的代碼片段是遞歸地將你的根目錄的文件夾內的鍵盤映射。這就是爲什麼你看到意外的行爲。

希望這會有所幫助!

+0

我之前測試過你的方法,當我嘗試創建一個新文件夾時,它能夠檢測到,但是當我嘗試將該文件放入新創建的文件夾時,它無法檢測到新文件,因此我開發我的程序變得像根據我在網上找到的東西 – attack

+0

但你有沒有說過你應該只能監視* root *目錄而不是子文件夾? – anacron