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

时间:2011-11-13 03:26:08

标签: java nio filesystemwatcher java-7

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

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

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

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

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

  3. 您是否知道如何使锁定或者至少让用户能够以经典方便的方式删除这样的目录结构?

2 个答案:

答案 0 :(得分:2)

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

在我的c:\ temp目录中,我以编程方式创建一个c:\ temp \ a dir,然后创建一个c:\ 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();
        }

然后我将观察者添加到“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();
        }
    }

这没关系,如果我修改“a”或“b”中的文件,我会得到相应的控制台输出。

使用Windows资源管理器(在Windowx XP机器上)确实无法删除已监视的目录(它告诉我我没有访问权限)。但是我可以使用其他工具删除它,例如Total Commander。我甚至可以使用rd c:\temp\a\b从Windows命令行删除。我认为这对Windows资源管理器来说比使用Java更具问题......

答案 1 :(得分:-1)

关于你的第二个问题,如果你得到异常“新创建的文件夹被另一个进程使用而且无法访问它”。您可以尝试在代码中使用 Atomic Operations 。这将有助于操作不被中断,并可以解决您的问题。