2016-09-26 129 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