【问题标题】:Delete and recreate a file/directory删除并重新创建文件/目录
【发布时间】:2018-10-24 14:39:17
【问题描述】:

我正在努力解决一个目录及其内容被删除然后由不同进程重新创建的问题。

但是,删除过程似乎仍然保持文件句柄打开,并导致在尝试重新创建时抛出AccessDeniedException。任何帮助将不胜感激。示例代码如下:

private static void deleteFilesAndDirectories(Path targetPath, Predicate<? super Path> filter) {
    try {
        try (Stream<Path> eligibleFiles = Files.walk(targetPath)
                .filter(path -> !Files.isDirectory(path))
                .filter(filter)) {

            for (Path file : eligibleFiles.collect(Collectors.toList())) {
                if (Files.isDirectory(file)) {
                    deleteFilesAndDirectories(file, filter);
                }

                Path parentDir = file.getParent();
                Files.delete(file);

                //Delete holding directory
                if (Files.list(parentDir).count() == 0) {
                    Files.delete(parentDir);
                }
            }
        }

    } catch (IOException e) {
        logger.error("Failed to delete directory");  //AccessDeniedException is caught
    }
}

public static void delete(String subdirectory) {
  deleteFilesAndDirectories(Paths.get(subdirectory), path -> true);
}

public static void store(MultipartFile file, String subdirectory) {
  Path subdirectoryPath = Paths.get(subdirectory);

  if (!Files.isDirectory(subdirectoryPath)) {
  try {
    Files.createDirectories(subdirectoryPath);

  } catch (IOException e) {
    throw new StorageException("Could not create sub-directory " + subdirectoryPath.toAbsolutePath(), e);
  }
}

public static void main(String[] args) {
  MultipartFile file = ...;

  delete("mydir"); //Attempts to delete directory, but is still visible in Windows Explorer though access is denied when trying to go into it

  store(file, "mydir");  //Checks if directory already exists, and attempts to create if not there.
}

在执行Files.createDirectories(subdirectoryPath) 时打印堆栈跟踪:

Caused by: java.nio.file.AccessDeniedException: D:\Workspaces\***\application\pending\0
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:504)
at java.nio.file.Files.createDirectory(Files.java:674)
at java.nio.file.Files.createAndCheckIsDirectory(Files.java:781)
at java.nio.file.Files.createDirectories(Files.java:767)

【问题讨论】:

  • 从你在代码中的注释看来AccessDeniedException出现在delete方法中。
  • @Razeen 你可以输入代码e.printStackTrace(); 来捕获失败并在他的问题中报告吗?只有打印堆栈错误消息对检查问题很重要
  • 纯粹出于好奇:eligibleFilesStream whcih .filter(path -&gt; !Files.isDirectory(path))。然后你将Stream 收集到一个列表中,并使用 for 循环遍历文件。在这个循环中,您正在检查if (Files.isDirectory(file))。怎么会这样?
  • @Arnaud 不,delete 方法执行,但保留正在删除的对象(目录)。然后 store 方法尝试重新创建它,因为它无法确定它当前是否存在。
  • @LuCio 它的递归编程。如果一个目录有另一个目录,则清除该目录的文件和子目录。

标签: java file delete-file delete-directory


【解决方案1】:

问题出在这部分代码中:

if (Files.list(parentDir).count() == 0) {
    Files.delete(parentDir);
}

不幸的是,Files.list(Path) 对该目录进行了某种锁定。这里有一个解决方法:

Stream<Path> list = Files.list(parentDir);
int count = list.count();
list.close();
if (0 == count) {
    Files.delete(parentDir);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多