java.nio.file.Files.delete(Path path) - 使用 SimpleFileVisitor 递归删除目录偶尔失败

2024-03-13

尝试解决偶尔出现的问题java.nio.file.DirectoryNotEmptyException在递归删除方法中取自Java中递归删除目录 https://stackoverflow.com/questions/779519/delete-files-recursively-in-java/8685959#8685959

Code(归功于@TrevorRobinson):

static void removeRecursive(Path path) throws IOException {
    Files.walkFileTree(path, new SimpleFileVisitor<Path>() {

        final Logger logger = LoggerFactory.getLogger(this.getClass());
        @Override
        public FileVisitResult visitFile(Path file,
                BasicFileAttributes attrs) throws IOException {
            logger.warn("Deleting " + file.getFileName());
            Files.delete(file);
            logger.warn("DELETED " + file.getFileName());
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) {
            // try to delete the file anyway, even if its attributes could
            // not be read, since delete-only access is theoretically possible
            // I NEVER SEE THIS
            logger.warn("Delete file " + file + " failed", exc);
            try {
                Files.delete(file);
            } catch (IOException e) {
                logger.warn(
                    "Delete file " + file + " failed again", exc);
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
                throws IOException {
            if (exc == null) {
                Files.delete(dir);
                return FileVisitResult.CONTINUE;
            }
            // directory iteration failed; propagate exception
            throw exc;
        }
    });
}

Call:

try {
    removeRecursive(Paths.get(unzipDirPath));
} catch (IOException e) {
    String msg = "Failed to delete folder " + unzipDirPath;
    if (e instanceof java.nio.file.DirectoryNotEmptyException) {
        msg += ". Still contains : ";
        final File[] listFiles = Paths.get(unzipDirPath).toFile().listFiles();
        if (listFiles != null) for (File file : listFiles) {
            msg += file.getAbsolutePath() + "\n";
        }
    }
    log.error(msg, e);
}

Prints(20/40 次迭代一次):

22:03:34.190 [http-bio-8080-exec-47] WARN  g.u.d.m.server.servlets.Controller$1 - Deleting batt
22:03:34.192 [http-bio-8080-exec-47] WARN  g.u.d.m.server.servlets.Controller$1 - DELETED batt
22:03:34.192 [http-bio-8080-exec-47] WARN  g.u.d.m.server.servlets.Controller$1 - Deleting wifi
22:03:34.193 [http-bio-8080-exec-47] WARN  g.u.d.m.server.servlets.Controller$1 - DELETED wifi
22:03:34.196 [http-bio-8080-exec-47] ERROR g.u.d.m.s.s.DataCollectionServlet - Failed to delete folder C:\yada\. Still contains : C:\yada\dir\wifi

java.nio.file.DirectoryNotEmptyException: C:\yada\dir
    at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:265) ~[na:1.7.0_45]
    at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103) ~[na:1.7.0_45]
    at java.nio.file.Files.delete(Files.java:1077) ~[na:1.7.0_45]
    at gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:128) ~[Controller$1.class:na]
    at gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:1) ~[Controller$1.class:na]
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:224) ~[na:1.7.0_45]
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:199) ~[na:1.7.0_45]
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69) ~[na:1.7.0_45]
    at java.nio.file.Files.walkFileTree(Files.java:2600) ~[na:1.7.0_45]
    at java.nio.file.Files.walkFileTree(Files.java:2633) ~[na:1.7.0_45]
    at gr.uoa.di.monitoring.server.servlets.Controller.removeRecursive(Controller.java:96) ~[Controller.class:na]
    at gr.uoa.di.monitoring.server.servlets.DataCollectionServlet.doPost(DataCollectionServlet.java:153) ~[DataCollectionServlet.class:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [servlet-api.jar:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [servlet-api.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.32]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [catalina.jar:7.0.32]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [catalina.jar:7.0.32]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [catalina.jar:7.0.32]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [catalina.jar:7.0.32]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [catalina.jar:7.0.32]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) [catalina.jar:7.0.32]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.32]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [catalina.jar:7.0.32]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) [tomcat-coyote.jar:7.0.32]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) [tomcat-coyote.jar:7.0.32]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-coyote.jar:7.0.32]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_45]
    at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45]

请注意wifi被报告为已删除 - 更奇怪的是有时我得到:

无法删除文件夹 C:\yada。仍然包含:C:\yada\dir

java.nio.file.DirectoryNotEmptyException: C:\yada\dir

我倾向于得出这样的结论:有时删除会花费太长时间 - 换句话说,问题在于java.nio.file.Files.delete(Path path)不会阻塞(因此 C:\yada\dir 仍然包含文件,有时在我统计它时会被删除)。那么我该如何解决这个问题呢?

Also : is java.nio.file.Files.delete(Path path)需要扔?这docs http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#delete%28java.nio.file.Path%29 state :

在某些操作系统上,当该 Java 虚拟机或其他程序打开并使用文件时,可能无法删除该文件。

在这种情况下似乎不需要抛出异常。Is java.nio.file.Files.delete(Path path)需要扔 ?


我遇到了同样的问题,结果发现问题是由我从中删除内容的同一目录的代码中其他位置的未关闭目录文件流引起的。返回的流对象:

Files.list(Path)

必须关闭,因此如果使用该方法,请务必在代码中使用 try-with-resources 构造。

所以我不认为删除时间太长,我在重新尝试删除目录之前尝试等待,但没有任何运气。您自己的程序很可能已锁定该资源。结果是,尽管它成功返回,但对其的删除调用并未完成(看起来一旦您自己的程序释放该文件,Windows 最终将删除该文件),但是当然无法删除包含的目录,因为它确实还没有删除空的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java.nio.file.Files.delete(Path path) - 使用 SimpleFileVisitor 递归删除目录偶尔失败 的相关文章

  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • dispatch_write() 和dispatch_read() 用法

    我只是在玩一些 GCD 函数来向文件写入和读取数据 其中两个函数是dispatch write and dispatch read 它允许向文件描述符写入和读取数据 而无需设置新的dispatch io t渠道 所以 我有以下代码 impo
  • Java:BufferedInputStream 的 available() 方法存在问题

    我正在处理以下代码 用于将大文件拆分为一组较小的文件 FileInputStream input new FileInputStream this fileToSplit BufferedInputStream iBuff new Buff
  • 为什么 Cassandra 客户端在生产中没有 epoll 时会失败? [复制]

    这个问题在这里已经有答案了 当我在本地运行服务时 我收到一条警告 指出 epoll 不可用 因此它使用 NIO 很公平 当我将其部署到 Kubernetes 中时 我得到了以下信息 这导致服务无法运行 2017 03 29T19 09 22
  • Selector.close() 是否关闭所有客户端套接字?

    我是 nio 套接字的新手 我已经使用 nio 套接字编写了一个服务器 现在我正在尝试编写关闭钩子以确保通过清理资源正常退出 我的问题是Selector close 方法关闭所有客户端套接字 如果没有 请告诉我如何访问所有客户端套接字 而无
  • windows XP中如何设置默认编码?

    我尝试使用 StreamReader 打开文件并设置编码 但我希望它采用默认 Windows 编码 我如何更改我的 Windows 编码 区域和语言选项控制面板项目 高级选项卡 影响整个计算机
  • 文件加密与解密问题

    我一直在尝试在 VC Express 2010 中加密和解密文件 我见过的所有教程和文档都需要两个FileStreams 来加密文件 一个用于读取未加密的版本 另一个用于加密 当我实际编写代码时 它不断抛出错误 告诉我它无法打开该文件 因为
  • 为 python 的 csv 阅读器中的特定行添加下标?

    我希望能够通过 csv 阅读器访问 csv 文件的特定行 例如第四行 有没有办法用 python 的 csv reader 模块来做到这一点 您只需解析所有 CSV 文件 然后使用正常的排序索引即可 否则 你可以做这样的事情 def my
  • 自 Java 7 以来 HttpServer 延迟 1 秒

    我们正在使用内部HttpServer项目中的类 用于通过 HTTP 在客户端和服务器之间交换数据 当我们切换到 Java 7 时 我们意识到结果交付存在延迟 我们可以将问题简化为以下示例 Class EchoServer创建上下文 echo
  • Java 读取大文本文件时出现 OutOfMemoryError

    我是 Java 新手 正在读取非常大的文件 需要一些帮助来理解问题并解决它 我们有一些遗留代码 必须对其进行优化才能正常运行 文件大小仅在 10mb 到 10gb 之间变化 只有当文件开始大小超过 800mb 时才会出现启动问题 Input
  • 快速写入:内存映射文件与 BufferedWriter

    有人对此进行过基准测试吗 我希望尽可能快地写入磁盘 最大限度地减少写入调用的延迟 我想知道写入内存映射缓冲区 通过 buffer put 是否比仅在 Java 端缓冲内容并在缓冲区满后刷新到 fileChannel 更快 这样 一旦缓冲区已
  • 为什么 fgets 函数被弃用?

    From GNU C 编程教程 http crasseux com books ctutorial fgets html The fgets file get string 功能与gets类似 功能 这个函数是已弃用 这意味着它已经过时了
  • 在Java中读取制表符分隔的文件

    我有以下代码来读取 Java 中的制表符分隔文件 while str in readLine null if str trim length 0 continue String values str split t System out p
  • 使用 FILE_FLAG_NO_BUFFERING 会带来明显的速度增益吗?

    最近在MSDN中注意到FILE FLAG NO BUFFERING标志的详细描述 并阅读了几条关于Windows中无缓冲I O的Google搜索结果 http msdn microsoft com en us library aa36385
  • 显示文件夹并建立这些文件夹的链接

    我正在寻找用 PHP 构建一个目录浏览器 我刚刚开始编写代码 但需要有人帮助我完成或修改它 dir dirname FILE path of the directory to read iterator new RecursiveDirec
  • Python无法识别目录 os.path.isdir() [重复]

    这个问题在这里已经有答案了 我有以下 Python 代码来删除目录中的文件 由于某种原因 我的 svn 目录未被识别为目录 我得到以下输出 svn 不是目录 任何想法 将不胜感激 def rmfiles path pattern patte
  • 如何在 OpenCV 中将 Float Mat 写入文件

    我有一个矩阵 Mat B 480 640 CV 32FC1 包含浮点值 我想将此矩阵写入一个可以打开的文件Notepad https en wikipedia org wiki Windows Notepad or 微软Word https
  • 文件输出流到文件输入流

    将 FileOutputStream 转换为 FileInputStream 的最简单方法是什么 一段代码就很好 这可能对您有帮助 http ostermiller org convert java outputstream inputst
  • java.nio TransferTo 似乎快得不可思议?

    有人可以解释一下如何transferTo方法可以以每秒 1000 MB 的速度复制文件 我使用 372MB 二进制文件运行了一些测试 第一个副本很慢 但如果我更改输出名称并再次运行它 输出目录中会在短短 180 毫秒内出现一个附加文件 结果
  • NIO 直接缓冲区何时以及如何被释放?

    我有一个 C 库 需要一个临时缓冲区作为暂存空间 我正在考虑将直接字节缓冲区的地址传递给它 在最终释放缓冲区之前 是否允许虚拟机重新定位缓冲区 JNI 框架消失后 本机库将保留该指针 我的理解是 JNI 本地对象引用无法缓存 因为 VM 可

随机推荐