Java nio FileSystem Watcher锁定目录.删除变得不可能

Mar*_*ano 8 java nio filesystemwatcher java-7

我正在使用Java7的新功能来查看目录以进行更改(如以下教程中所述:http://download.oracle.com/javase/tutorial/essential/io/notification.html)

观看本身(几乎)没有问题.

或多或少我有两个问题,我希望你们中的一些人知道如何处理它.

  1. 添加一个文件夹进行监视后,VM可以访问它并且不会释放它.这应该不是一个大问题.但是,如果您要在另一个目录中创建一个目录,那么还要创建一个目录.(例如,你在目录中创建c:\tmp\a的目录bb目录c(c:\tmp\a\b\c)),它是无法删除的目录a,因为虚拟机的访问,bc.如果要删除所有文件夹(例如,使用Windows资源管理器)c,则必须先删除,然后b再删除a.这很奇怪,但这种方式有效(虽然不方便)

  2. 这个问题似乎是第一个问题的结果.如果a有时会发生很多变化(或多或少)我得到一个异常,告诉我,新创建的文件夹被另一个进程使用,并且无法访问它.这很奇怪,因为我认为收到通知并不重要.并且因为在完全抛出此异常时并不完全清楚.

你有没有想法如何使没有锁或至少让用户能够以经典方便的方式删除这样的目录结构?

Shi*_*gon 2

好吧,我已经尝试过您发布的链接中显示的代码,执行与您尝试执行的操作相同的操作:

在我的 c:\temp 目录中,我以编程方式创建 ac:\temp\a 目录,然后创建 ac:\temp\a\b 目录:

File startDir = new File("c:\temp");
        if(!startDir.exists()) {
            startDir.mkdir();
        }
        File aDir = new File("c:\\temp\\a");
        File bDir = new File("c:\\temp\\a\\b");
        if(!aDir.exists()) {
            aDir.mkdir();
        }
        if(!bDir.exists()) {
            bDir.mkdir();
        }
Run Code Online (Sandbox Code Playgroud)

然后我将观察者添加到“a”和“b”目录中:

public static void watch(final File dir,final WatchService watcher) {
        Path path = dir.toPath();
        try {
            final WatchKey bDirWatchKey = path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("Watching: "+dir.getName());
                    while(true) {
                        try {Thread.sleep(1000);} catch (InterruptedException e) {}
                        List<WatchEvent<?>> events = bDirWatchKey.pollEvents();
                        for(WatchEvent<?> event:events) {
                            System.out.println(dir.getName()+" event: #"+event.count()+","+event.kind()+" File="+event.context());
                        }
                    }                   
                }
            }).start();
        } catch (IOException x) {
            x.printStackTrace();
        }
    }
Run Code Online (Sandbox Code Playgroud)

这工作正常,如果我修改“a”或“b”中的文件,我会得到相应的控制台输出。

确实,使用 Windows 资源管理器(在 Windowx XP 计算机上)我无法删除监视的目录(它告诉我没有访问权限)。不过,我可以使用 Total Commander 等其他工具删除它。我什至可以使用 Windows 命令行删除它rd c:\temp\a\b。我认为这更多是 Windows 资源管理器的问题,而不是 Java 的问题......