2016-09-26 57 views
0

在java中,當我添加,更改或刪除任何文件時,我希望程序在另一個目錄中執行相同的操作。這意味着,如果我添加一個文件「test.txt」在E:// aaa中,程序應該從E:// aaa複製「test.txt」到D:// bbb。如何在WatchService中獲得真正的路徑

我使用java.nio.file.WatchService來實現它,但我無法獲取文件的真實路徑程序,這是我的代碼:

public void watchPath(Path watchPath, Path targetPath) throws IOException, InterruptedException { 
    try (WatchService watchService = FileSystems.getDefault().newWatchService()) { 
     watchPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, 
       StandardWatchEventKinds.ENTRY_DELETE); 
     while (true) { 
      final WatchKey key = watchService.take(); 
      for (WatchEvent<?> watchEvent : key.pollEvents()) { 
       final Kind<?> kind = watchEvent.kind(); 
       if (kind == StandardWatchEventKinds.OVERFLOW) { 
        continue; 
       } 
       final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent; 
       Path systemFileDir = (Path) key.watchable(); // TODO Here can not get the real path 
       //System.out.println(systemFileDir.toString()); // E:/aaa 
       //System.out.println(systemFileDir.toAbsolutePath()); // E:/aaa 
       //System.out.println(systemFileDir.toRealPath()); // E:/aaa 
       final Path path = watchEventPath.context(); 
       String fileAbsPath = systemFileDir + File.separator + path; 
       Path original = Paths.get(fileAbsPath); 
       String targetAbsPath = fileAbsPath.replace(watchPath.toString(), targetPath.toString()); 
       Path target = Paths.get(targetAbsPath); 
       File file = new File(targetAbsPath); 
       if (kind == StandardWatchEventKinds.ENTRY_CREATE || kind == StandardWatchEventKinds.ENTRY_MODIFY) { 
        if (file.isDirectory() && !file.exists()) { // 如果是目錄 
         file.mkdirs(); 
        } else { 
         Files.copy(original, target, StandardCopyOption.REPLACE_EXISTING); 
        } 
       } 
       if (kind == StandardWatchEventKinds.ENTRY_DELETE) { 
        Files.delete(target); 
       } 
      } 
      boolean valid = key.reset(); 
      if (!valid) { 
       break; 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

現在的問題是,當我在E添加一個文件或目錄:// AAA/X,程序不能得到真正的路徑。例如,我添加了文件E://aaa/x/test.txt,我希望我能得到這個絕對路徑,然後將它複製到目的地,但我只是得到RootPath E:// aaa。

如何我可以解決它嗎?謝謝!

回答

0

基於您的評論:

你有這個問題的原因是因爲你永遠只註冊父文件夾。如果你想得到一個在子文件夾中編輯的確切路徑,那麼你需要在這些子文件夾中註冊你的觀察者。一種方法是在開始時對walk through the entire file tree進行註冊。

這裏是一個很好的例子:

http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java

現在你只需要修改的代碼片段通過調整processEvents()方法適合您的需要檢查事件類型,然後使用child變量做您的其他文件夾中的相同動作。

這裏是一個編輯的原油例如,你可以作出processEvents去了解你的鏡像目錄添加文件夾:

Path child = dir.resolve(name); 
    if (kind == StandardWatchEventKinds.ENTRY_CREATE && (check if directory here)) 
    { 
     String destinationToMirror = "D" + child.toString().substring(1); 
     File file = new File(destinationToMirror); 
     file.mkdir(); 
    } 

否則讀了行走的文件樹,以便你可以添加必要的位自己的代碼: http://docs.oracle.com/javase/tutorial/essential/io/walk.html


原來的答案:

嘗試是這樣的:

Path original = systemFileDir.resolve(watchEventPath.context()); 

相反的:

final Path path = watchEventPath.context(); 
String fileAbsPath = systemFileDir + File.separator + path; 
Path original = Paths.get(fileAbsPath); 

注意的主要區別是路徑是如何解決使用dir.resolve

信用:java.nio.file.WatchEvent gives me only relative path. How can I get the absolute path of the modified file?

+0

如果我添加E:\\ aaa \ x中的一個文件夾,我想要得到路徑「E:\\ aaa \ x \ y」,但是'systemFileDir.resolve(watchE ventPath.context())'剛剛返回「E:\\ aaa \ x」,我不知道如何讓我的新文件夾名稱爲「y」。 – Leon

+0

@JasonGan查看我的編輯。但實質上:http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java – sorifiend

相關問題