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 递归删除目录偶尔失败 的相关文章

  • PHP gzuncompress 出现文件读写错误

    我有一个函数可以跟踪脚本中发生的事件 为了有效地利用我的资源 我决定压缩它生成的数据 但是 我不断收到此错误 Unknown error type 2 gzuncompress function gzuncompress data erro
  • file.canWrite() 说“true”,但我无法在可移动存储上写入(kit kat)

    我收到来自相机的意图 其中包含在此路径中拍摄的照片 storage extSdCard DCIM Camera photoCaptured jpg 我想调整图像的大小 已经这样做了 并在同一路径中覆盖 我可以在 2 3 4 1 和 4 3
  • 从 airodump-ng 读取实时输出

    当我执行命令 airodump ng mon0 gt gt output txt 时 output txt 为空 我需要能够运行 airodump ng mon0 并在大约 5 秒后停止该命令 然后才能访问其输出 有什么想法我应该从哪里开始
  • 如何获取文件目录的绝对路径?

    如何获取包含指定文件的目录的绝对路径 current dir is home me dev File file new File target test txt assert absolute file equals home me dev
  • 如何设置IntelliJ IDEA项目SDK

    我刚刚安装了 IntelliJ IDEA 当我尝试创建我的第一个项目时 它要求我设置项目 SDK 当我单击 JDK 时 它要求我选择 JDK 的主目录 如下图所示 我无法找到它在哪里 对于新项目 选择 jdk 的主目录 eg C Java
  • 使用 DataInputStream 从文件读取非常慢

    我有一个包含大量数字的文件 我尝试使用以下代码从文件中读取它 但是速度非常慢 任何人都可以帮助减少时间吗 以下是我以非常慢的方式读取它的代码 import java io BufferedInputStream import java io
  • 使用 Python 移动特定文件类型

    我知道这对你们中的许多人来说会非常容易 我刚刚开始学习 Python 需要一些基本文件处理方面的帮助 我拍摄了很多屏幕截图 最终出现在我的桌面上 因为这是默认设置 我知道我可以更改屏幕截图设置以自动将其保存在其他位置 不过 我认为这个程序将
  • 编译器错误:对调用的引用不明确

    Case 1 static void call Integer i System out println hi i static void call int i System out println hello i public stati
  • 从 CSV 文件读取数据并将其显示在 JTable 中

    我正在尝试从 CSV 文件读取数据并将其显示在 JTable 上 但遇到一些问题 我是菜鸟所以请耐心等待 我查看并合并了多个来源的示例代码 但无济于事 该表显示但它是空白的 我知道我正在读取数据 因为我可以打印它 我怀疑我的 ModelTa
  • 将数据写入文本文件

    我有一个简单的程序 将 7 个数字中的 6 个写入文本文件 从逻辑上讲 一切似乎都很好 但是 数字并未按预期写入文件 Random random new Random Console WriteLine Please enter the n
  • 在Python中写入文件之前如何确保文件存在或可以创建?

    我正在编写一个函数 我希望它能够touch一个文件 以便我可以写入该文件 如果该文件不存在 我会收到错误消息 我怎么能这么说呢 只需打开要写入的文件 如果该文件不存在 则会创建该文件 假设您具有写入该位置的适当权限 f open some
  • 使用 C# 读取数百万个小文件

    我有数百万个每天生成的日志文件 我需要读取所有这些文件并将其放在一起作为单个文件 以便在其他应用程序中对其进行一些处理 我正在寻找最快的方法来做到这一点 目前我正在使用线程 任务和并行 如下所示 Parallel For 0 files L
  • 读写文本文件的最佳方法

    我正在使用最新版本的 Lazarus IDE 并且我有一个Memo1在我的 TForm1 上 我必须加载一个文本文件Memo1然后编辑备忘录的每一行 我使用Memo1 Lines Strings i 最后 我必须将编辑后的备忘录保存在特定路
  • 在文件夹之间移动文件

    我想使用 R 将文件从一个文件夹复制 粘贴到 Windows 中的另一个文件夹 但它不起作用 我的代码 gt file rename from C Users msc2 Desktop rabata txt to C Users msc2
  • 在Python中的自定义类中实现“with object() as f”的使用

    我必须在 python 中打开一个类似文件的对象 它是通过 dev 的串行连接 然后关闭它 在我的班级的几种方法中 这已经完成了好几次 我的做法是在构造函数中打开文件 然后在析构函数中关闭它 不过 我遇到了奇怪的错误 我认为这与垃圾收集器有
  • 读取输入文件的部分内容

    我想读取 C 中的输入文件 其结构 或缺乏 将类似于一系列带有以下内容的行 文字 数字 例如 input1 10 input2 4 set1 1 2 set2 1 e3 我想把这个号码从队列中取出 然后把剩下的扔掉 数字可以是整数或双精度数
  • 如何使用 file_put_contents() 写入变量值?

    一整天都在试图解决这个问题 假设这只是一个小错误 我正在尝试使用file put content将变量值放入另一个 php 文件中 下面的代码将解释 将数据写入php的文件
  • 如何在书架中取出整数钥匙?

    我想在架子上存储一个整数密钥 但是当我尝试将整数密钥存储在搁置中时 它给了我一个错误 Traceback most recent call last File write py line 12 in data id Id id Name n
  • 在Python中获取目录基名的优雅方法?

    我有几个脚本将目录名称作为输入 并且我的程序在这些目录中创建文件 有时我想获取给程序的目录的基本名称 并用它在目录中创建各种文件 例如 directory name given by user via command line output
  • 如果防火墙打开,Java 7 会阻止 Windows Vista 和 7 上的 FTP 传输。有任何想法吗?

    Java 7 阻止 Windows Vista 和 7 上的 FTP 传输 在 FTP 中 在传输文件之前 必须发送 PORT 或 PASV 命令 一旦发送其中一个命令 Windows 防火墙就会关闭发送该命令的套接字 仅当防火墙打开并且

随机推荐