【问题标题】:Deleting Empty directory in java在java中删除空目录
【发布时间】:2021-03-24 18:51:26
【问题描述】:

场景:

路径:/users/country/CAN/DateFolder1 更多目录 /users/country/CAN/DateFolder2 /users/country/CAN/DateFolder3

DateFolder1 和 DateFolder2 为空。

我想在日期文件夹为空时删除它们,但我不能专门提及日期文件夹名称

使用下面,我可以删除目录直到我提到的路径,但需要逻辑来搜索。仅在指定路径之后的内部目录。

FileSystemUtils.deleteRecursively(Paths.get("/Users/country/CAN/"));

【问题讨论】:

  • 请为您的帖子应用合适的文本/代码格式选项以提高可读性。

标签: java file fileutils


【解决方案1】:

不重复删除 /users/country/CAN 中的空文件夹:

File dataFolder = new File("/users/country/CAN");
File[] dataFolderContent = dataFolder.listFiles();
if (dataFolderContent != null && dataFolderContent.length > 0) {
    for (File item : dataFolderContent) {
        if (item.isDirectory()) {
            File[] itemContent = item.listFiles();
            if (itemContent != null && itemContent.length == 0) {
                item.delete();
            }
        }
    }
}

更新。 例如根文件夹是/users/country,我们需要从根目录中删除一定深度的所有空文件夹。如果您的评论深度= 2。 我使用了最简单的 IO,因为任务很简单。如果你想要 NIO,你可以找到有关 Files.walk(Path path, int depth) 的信息。

public void deleteEmpty(File folder, int depth) {
    if (folder.isDirectory()) {
        if (depth == 0) {
            String[] folderContent = folder.list();
            if (folderContent != null && folderContent.length == 0) {
                folder.delete();
            }
        } else {
            depth--;
            File[] listFiles = folder.listFiles();
            if (listFiles != null && listFiles.length > 0) {
                for (File file : listFiles) {
                    deleteEmpty(file, depth);
                }
            }
        }
    }
}

更新 2. NIO 示例。

final int targetDepth = 2;
final Path path = Paths.get("/users/country");
try (Stream<Path> walk = Files.walk(path, targetDepth)) {
    walk.filter(Files::isDirectory).forEach(folderPath -> {
        if ((folderPath.getNameCount() - path.getNameCount()) == targetDepth) {
            File folder = folderPath.toFile();
            String[] list = folder.list();
            if (list != null && list.length == 0) {
                folder.delete();
            }
        }
    });
}

【讨论】:

  • 请避免使用旧的繁琐文件API,改用NIO。
  • 感谢@Aleksandr,它起作用了.. 还有一个问题.. 假设还有多个国家文件夹 -->/users/country/CAN -->/users/country/USA 在这个案例,你会如何遍历所有国家,但不删除国家文件夹,只删除里面的文件夹
  • @amandeepgandhi 查看更新。希望对你有帮助。
  • @Zabuzard NIO 添加了。
【解决方案2】:

更新:以下答案已更新以反映预期内容。

我也在考虑 Java NIO API,但已经有一个公认的答案, 不过这里有一个使用 Java NIO 的 API

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.stream.Stream;

class Scratch extends SimpleFileVisitor<Path> {
    private static final Path basePath = Paths.get("/tmp/1");
    public static void main(String[] args) throws IOException {
        Scratch scratch = new Scratch();
        Files.walkFileTree(basePath, scratch);
    }


    @Override
    public java.nio.file.FileVisitResult postVisitDirectory(java.nio.file.Path dir, java.io.IOException exc) throws java.io.IOException {
        return super.postVisitDirectory(dir, exc);
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        if(attrs.isDirectory() && isEmpty(dir)) {
            if(dir.getParent().equals(basePath)) {
                System.out.printf("skipped dir %s since it is a direct descendant of %s\n", dir, basePath);
                return FileVisitResult.CONTINUE;
            }
            Files.delete(dir);
            System.out.println("deleted dir = " + dir);
            return FileVisitResult.SKIP_SUBTREE;
        }

        return FileVisitResult.CONTINUE;
    }

    // https://www.baeldung.com/java-check-empty-directory
    public static boolean isEmpty(Path path) throws IOException {
        if (Files.isDirectory(path)) {
            try (Stream<Path> entries = Files.list(path)) {
                return entries.findFirst().isEmpty();
            }
        }

        return false;
    }
}

之前:

输出:

之后:

【讨论】:

  • 我需要如下结果:当前:/tmp/1 ->一个->文件夹(空)->两个->文件夹(空)->三个->文件夹->文件->四个-> 文件夹 -> 文件 之后:/tmp/1 -> 一 -> 二 -> 三 -> 文件夹 -> 文件 -> 四 -> 文件夹 -> 文件 所以基本上我不想要文件夹一,二,三四永远被删除,只有当它们为空时它里面的子文件夹
  • 答案更新了,应该做你想做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2010-10-21
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多