如何使用Java删除包含文件的文件夹

Mr.*_*r.G 95 java file-io delete-directory

我想使用Java创建和删除目录,但它无法正常工作.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 162

只是一个班轮.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));
Run Code Online (Sandbox Code Playgroud)

文档在这里

  • @ searchengine27不,你完全忽略了这一点.需要大量律师允许使用apache公共资源的公司是绝对的病态,并且在IT世界中没有任何规范.我从来没有听说过有人遇到过这样的问题,如果你遇到这样的问题,你很可能会被SO封锁,所以无论如何你都无法获得答案. (13认同)
  • 不.这是一个带有外部依赖的单行,这是一个重要的事情要记住.唯一一次使用像这样的外部依赖是这么简单就是当你做个人家庭项目,或者你的公司真的不关心被起诉的可能性. (9认同)
  • @ searchengine27但是看起来这个库是在Apache Commons下的,因此被起诉的风险可以忽略不计https://www.whitesourcesoftware.com/whitesource-blog/top-10-apache-license-questions-answered/. (7认同)
  • @simtim你完全没有抓住要点。如果没有律师团队首先仔细研究使用条款和最终用户协议以及与库相关的任何其他法律文件,公司永远不会批准库的使用。必须有人付钱给这些律师……有时没有人愿意,这意味着开发商无法使用它。你工作的公司越大,你必须经历的繁文缛节就越多。 (3认同)
  • @searchengine27 我曾在大型企业公司工作过,可以确认他们确实允许您使用开源库,这只是现代软件开发的事实。然而,在我的前雇主,他们确实保留了所有依赖项的长列表,包括传递依赖项及其许可证。如果许可证不在标准列表中(例如 EPL、MPL、Apache 等),那么我们必须获得特定批准。但它肯定不需要一大群律师 (3认同)

Jef*_*man 91

这是有效的,虽然跳过目录测试看起来效率低,但它不是:测试立即发生listFiles().

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}
Run Code Online (Sandbox Code Playgroud)

更新,以避免遵循符号链接:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}
Run Code Online (Sandbox Code Playgroud)

  • 事实证明,这有一个错误.如果另一个进程在循环期间删除文件,则可能导致应捕获并忽略的异常. (2认同)
  • @ 9ilsdx9rvj0lo与其说是笨拙,不如您可以提供编辑以处理符号链接。OP在他的帖子中“什么都没说”关于符号链接。只需创建和删除目录。还请列出“许多遗漏的东西”。帮助我们。 (2认同)
  • 这不是更好/更坏的问题,而是利弊。不依赖外部库有时会带来很大的好处。当然,使用久经考验的软件有很大的好处。由开发人员来平衡问题。如果除了已经提到的两个错误之外,还有其他错误,我们当然希望了解它们。 (2认同)

小智 89

Java无法删除包含数据的文件夹.您必须在删除文件夹之前删除所有文件.

使用类似的东西:

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}
Run Code Online (Sandbox Code Playgroud)

然后你应该能够使用index.delete() 未经测试删除该文件夹!

  • 这不会删除非空子目录. (35认同)
  • 你必须写一个递归方法或使用`FileUtils.deleteDirectory`作为@Francesco Menzani说. (13认同)
  • 要非常小心.如果index是另一个目录的符号链接,那么最终将删除其他目录的内容.不幸的是,我还没有找到一种在Java 6中检测Windows上符号链接的好方法,尽管Java 7提供了Files.isSymbolicLink(). (4认同)

And*_*hev 23

在JDK 7中,您可以使用Files.walkFileTree()Files.deleteIfExists()删除文件树.

在JDK 6中,一种可能的方法是从Apache Commons中使用FileUtils.deleteQuietly,它将删除文件,目录或带有文件和子目录的目录.

  • 以下是一个示例:http://fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html (5认同)

nir*_*mal 20

我更喜欢java 8上的这个解决方案:

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);
Run Code Online (Sandbox Code Playgroud)

从这个网站:http://www.baeldung.com/java-delete-directory

  • 这不是有文件句柄泄漏的问题吗?此示例_不_关闭由`Files.walk()` 返回的流,API 文档中明确指出了这一点。我知道,例如,如果您不关闭由`Files.list()` 返回的流,您可能会用完句柄并且程序会崩溃。参见例如 /sf/ask/2589303741/ 和 /sf/ask/1889806831/。 (3认同)
  • @shmosel因为 forEach 将从头开始删除,并且无法删除包含内容的目录。因此,必须将树转向相反的方向,从末端删除。 (3认同)
  • 请注意,这可能存在可伸缩性问题,因为它构建完整列表,创建排序副本,然后遍历排序副本.回到过去的记忆不是取之不尽的糟糕时期,这将是一个非常糟糕的主意.它简洁但空间成本(O(N)vs O(1))和效率(O(N log N)vs O(N)).这在大多数用例中都无关紧要. (2认同)
  • 这很优雅,有效并且不依赖于外部库。爱它 (2认同)

JRA*_*TLL 19

使用Apache Commons-IO,它遵循单行:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));
Run Code Online (Sandbox Code Playgroud)

这比(稍微)更高效FileUtils.deleteDirectory.


小智 9

我的基本递归版本,使用旧版本的JDK:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果在读取目录时存在I/O异常,则会抛出NullPointerException.代码应检查`listFiles()`是否返回null,而不是调用`isDirectory()`. (2认同)

小智 9

另一种选择是使用 Spring 的org.springframework.util.FileSystemUtils相关方法,它将递归删除目录的所有内容。

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);
Run Code Online (Sandbox Code Playgroud)

这将完成工作!


Bul*_*aza 8

这是最佳解决方案Java 7+:

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Gav*_*hen 7

如前所述,Java无法删除包含文件的文件夹,因此先删除文件,然后再删除文件夹。

这是执行此操作的一个简单示例:

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);
Run Code Online (Sandbox Code Playgroud)

要么:

FileUtils.forceDelete(new File(destination));
Run Code Online (Sandbox Code Playgroud)


Lau*_*tte 6

番石榴21+救援。仅当没有符号链接指向要删除的目录时才使用。

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;
Run Code Online (Sandbox Code Playgroud)

(此问题已由Google很好地索引,因此其他人usig Guava可能很乐意找到此答案,即使它与其他地方的其他答案是多余的。)


Jav*_*avo 5

我最喜欢这个解决方案。它不使用第3方库,而是使用Java 7的NIO2 。

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


小智 5

你可以试试这个

public static void deleteDir(File dirFile) {
    if (dirFile.isDirectory()) {
        File[] dirs = dirFile.listFiles();
        for (File dir: dirs) {
            deleteDir(dir);
        }
    }
    dirFile.delete();
}
Run Code Online (Sandbox Code Playgroud)