我尝试使用 Java 删除 NAS 上的文件和文件夹。一切正常,除非用户在我想要删除的文件夹中打开了 Windows 资源管理器。
例如,我有一个文件夹A,其中包含一个文件夹B。我想删除文件夹B,然后删除文件夹A。文件夹B将被删除,但文件夹A不会被删除。只有当有人在文件夹B中使用Windows资源管理器时才会发生这种情况。我的代码说文件夹A不为空,它仍然包含文件夹B。但这怎么可能,因为文件夹B刚刚被删除,并且在Windows资源管理器中我看不到文件夹B(即使检查了隐藏文件)。
我尝试在本地运行此代码,即使我在文件夹 B 中打开 Windows 资源管理器,它也能正常工作。这只发生在 NAS 上。你有什么想法吗?
boolean isSuccessfullyRemoved
void test(){
isSuccessfullyRemoved = true
Path p = Paths.get('FOLDER B')
try (def ds = Files.newDirectoryStream(p)) {
ds.each { subPath ->
// Delete every files in the folder B
if (subPath.toFile().isFile()) {
deleteFileorFolder(subPath)
}
}
}
// The folder B should be empty if the deletion of the files was successful and does not contains a folder
if (isSuccessfullyRemoved && isDirEmpty(p)) {
// Delete Folder B
deleteFileorFolder(p)
// Folder B has been deleted, isSuccessfullyRemoved is TRUE but isDirEmpty is FALSE, why?
if (isSuccessfullyRemoved && isDirEmpty(p.parent)) {
deleteFileorFolder(p.parent)
}
}
}
boolean isDirEmpty(Path directory) {
try (def ds = Files.newDirectoryStream(directory)) {
return !ds.iterator().hasNext()
}
}
void deleteFileorFolder(Path p) {
try {
Files.delete(p)
} catch (ignored) {
isSuccessfullyRemoved = false
}
}
不是答案,只是对重现此问题的更简单方法的观察:
// Setup a path to temp directory on NAS:
Path sub = Path.of("F:/Temp/Parent/Child/Sub");
Files.createDirectories(sub);
// Open explorer to Child
Desktop.getDesktop().open(sub.getParent().toFile());
Thread.sleep(10000L);
// Now try to delete
Files.delete(sub);
Files.delete(sub.getParent());
Files.delete(sub.getParent().getParent());
// If the explorer is open then the last delete fails with:
// => Exception java.nio.file.DirectoryNotEmptyException: F:\Temp\Parent
// at WindowsFileSystemProvider.implDelete (WindowsFileSystemProvider.java:270)
// at AbstractFileSystemProvider.delete (AbstractFileSystemProvider.java:104)
// at Files.delete (Files.java:1152)
如果不忽略异常,问题更容易发现:
static void deleteFileorFolder(Path p) {
System.out.println("deleteFileorFolder "+p);
Files.delete(p);
}