java中Path对象的文件路径不正确

时间:2016-12-30 03:56:53

标签: 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;
                   }
                });

    }

}

1 个答案:

答案 0 :(得分: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;
       }
    });
    
  3. 请使用:

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

    上面的代码片段将递归地将根目录的内部文件夹添加到keymap中。这就是你看到意外行为的原因。

    希望这有帮助!