Java nio FileSystem Watcher锁定目录。 删除变得不可能
我正在使用Java7的新function来查看更改目录(如以下教程中所述: http : //download.oracle.com/javase/tutorial/essential/io/notification.html )
观看本身(几乎)没有问题。
或多或少我有两个问题,我希望你们中的一些人知道如何处理它。
-
添加一个文件夹进行监视后,VM可以访问它并且不会释放它。 这应该不是一个大问题。 但是,如果您正在另一个目录中创建一个目录,那么还有一个目录。 (例如,您在目录
c:\tmp\a
中创建目录b
,在b
中创建目录c
(c:\tmp\a\b\c
))无法删除目录a
,因为访问了VM到b
和c
。 如果要删除所有文件夹(例如,使用Windows资源管理器),则必须首先删除c
,然后删除c
,然后删除a
。 这很奇怪,但这种方式有效(虽然不方便) -
这个问题似乎是第一个问题的结果。 如果有时发生了很多变化(或多或少)我得到一个exception,告诉我,新创建的文件夹被另一个进程使用,并且无法访问它。 这很奇怪,因为我认为收到通知无关紧要。 并且因为在完全抛出此exception时并不完全清楚。
您是否知道如何使锁定或者至少让用户能够以经典方便的方式删除这样的目录结构?
好吧,我已尝试在您发布的链接中展示的代码,执行您尝试执行的相同操作:
在我的c:\ temp目录中,我以编程方式创建ac:\ temp \ a dir,然后创建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(); }
然后我将观察者添加到“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> 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更具问题…
关于你的第二个问题,如果你得到exception“新创建的文件夹被另一个进程使用而且无法访问它”。 您可以尝试在代码中使用Atomic Operations 。 这将有助于操作不被中断,并可以解决您的问题。