File io java.nio.file.Files.delete(路径)-使用SimpleFileVisitor递归删除目录时偶尔出现故障

File io java.nio.file.Files.delete(路径)-使用SimpleFileVisitor递归删除目录时偶尔出现故障,file-io,java-7,nio,java-io,File Io,Java 7,Nio,Java Io,正在尝试对从中获取的递归删除方法中偶尔出现的java.nio.file.DirectoryNotEmptyException进行故障排除 代码(归功于@TrevorRobinson): 打印(每20/40次迭代一次): 22:03:34.190[http-bio-8080-exec-47]警告g.u.d.m.server.servlets.Controller$1-删除batt 22:03:34.192[http-bio-8080-exec-47]警告g.u.d.m.server.servlet

正在尝试对从中获取的递归删除方法中偶尔出现的
java.nio.file.DirectoryNotEmptyException
进行故障排除

代码(归功于@TrevorRobinson):

打印(每20/40次迭代一次):

22:03:34.190[http-bio-8080-exec-47]警告g.u.d.m.server.servlets.Controller$1-删除batt
22:03:34.192[http-bio-8080-exec-47]警告g.u.d.m.server.servlets.Controller$1-已删除batt
22:03:34.192[http-bio-8080-exec-47]警告g.u.d.m.server.servlets.Controller$1-删除wifi
22:03:34.193[http-bio-8080-exec-47]警告g.u.d.m.server.servlets.Controller$1-已删除wifi
22:03:34.196[http-bio-8080-exec-47]错误g.u.d.m.s.s.DataCollectionServlet-无法删除文件夹C:\yada\。仍然包含:C:\yada\dir\wifi
java.nio.file.DirectoryNotEmptyException:C:\yada\dir
在sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:265)~[na:1.7.0\u 45]
在sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)~[na:1.7.045]
在java.nio.file.Files.delete(Files.java:1077)~[na:1.7.0_45]
在gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:128)~[Controller$1.class:na]
在gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:1)~[Controller$1.class:na]
在java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:224)~[na:1.7.045]
在java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:199)~[na:1.7.045]
在java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69)~[na:1.7.045]
在java.nio.file.Files.walkFileTree(Files.java:2600)~[na:1.7.045]
在java.nio.file.Files.walkFileTree(Files.java:2633)~[na:1.7.0\u 45]
在gr.uoa.di.monitoring.server.servlets.Controller.removecursive(Controller.java:96)~[Controller.class:na]
在gr.uoa.di.monitoring.server.servlets.DataCollectionServlet.doPost(DataCollectionServlet.java:153)~[DataCollectionServlet.class:na]
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:641)[ServletAPI.jar:na]
在javax.servlet.http.HttpServlet.service(HttpServlet.java:722)[ServletAPI.jar:na]
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)[catalina.jar:7.0.32]
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)[catalina.jar:7.0.32]
在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)[catalina.jar:7.0.32]
在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)[catalina.jar:7.0.32]
在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)[catalina.jar:7.0.32]
在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)[catalina.jar:7.0.32]
在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)[catalina.jar:7.0.32]
在org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)[catalina.jar:7.0.32]
在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)[catalina.jar:7.0.32]
在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)[catalina.jar:7.0.32]
在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)[tomcat coyote.jar:7.0.32]
在org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)[tomcat coyote.jar:7.0.32]
在org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)[tomcat coyote.jar:7.0.32]
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)[na:1.7.0\u 45]
在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)[na:1.7.0_45]
在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)
不会阻塞(因此C:\yada\dir在它的时间到来时仍然包含文件,有时在我统计它时会被删除)。那么我该如何解决这个问题呢

:抛出是否需要
java.nio.file.Files.delete(路径)
?国家:

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


在这种情况下,似乎不需要抛出异常。抛出是否需要
java.nio.file.Files.delete(路径)
。当发生此异常时,捕获它并引发您自己的指定文件的异常

try {
 Files.delete(file);
} catch (DirectoryNotEmptyException  e) {
 throw new MySpecificException(file.getFileName());
}

class MySpecificException extends Exception {
 public MySpecificException() { }

 public MySpecificException(string filename) {
  super(filename);
 }  
}
可以使用
e.getMessage()获取文件名


我假设
Files.delete()
遇到无法删除的文件时,会继续删除目录中的文件。如果是这种情况,我的方法仍然有效:只需返回目录中所有文件的列表,而不是目录的文件名。它应该只包含不能删除的文件,而您仍然拥有您的解决方案。

以上我的评论的扩展

当Java在做某事时遇到问题时,它会抛出一个错误。与所有其他类型一样,异常可以从继承。API将指定每个方法抛出哪些选中的异常。
java.io
java中的方法。
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);
}
try {
 Files.delete(file);
} catch (DirectoryNotEmptyException  e) {
 throw new MySpecificException(file.getFileName());
}

class MySpecificException extends Exception {
 public MySpecificException() { }

 public MySpecificException(string filename) {
  super(filename);
 }  
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
       //You don't need to try to delete the file again since this method was called
       //because the deletion failed. Instead...
       if (exc instanceof NoSuchFileException) {
            System.out.println("Could not find the file: " + file);
       } else if (exc instanceof DirectoryNotEmptyException) {
            System.out.println("The directory [+ " file + "] was not empty.");
       } else {
            System.out.println("Could not delete file [" + file
                + "]. There was a problem communicating with the file system");
       }

       return FileVisitResult.CONTINUE;
}
Files.list(Path)
private boolean isDeleted(Path dir) throws IOException {
    boolean deleted = false;
    try {
        Files.delete(dir);
        deleted = true;
    } catch (DirectoryNotEmptyException e) {
    // happens sometimes if Windows is too slow to remove children of a directory
    deleted = false;
    }
    return deleted;
}
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
    if (e == null) {
        int maxTries = 5;
        int count = 0;
        boolean deleted = false;
        do {
            if ((deleted = this.isDeleted(dir))) {
                break;
            } else {
                // wait a bit and try again
                count++;
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e1) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        } while (count < maxTries);
        // gone?
        if (!deleted) {
            throw new DirectoryNotEmptyException(dir.toString());
        }
        // go ahead
        return FileVisitResult.CONTINUE;
    }
    throw e;
}
    /**  
     * @param dir The directory to list.
     * @return A list of files and directories in dir.
     * @throws IOException If encountered.
     */
    public static List<Path> getList(Path dir) throws IOException {
        try (Stream<Path> s = Files.list(dir)) {
            return s.collect(Collectors.toList());
        }
    }