【问题标题】:Delete a file and its parents directories if they're empty. ( Java )如果文件及其父目录为空,则删除它们。 (爪哇)
【发布时间】:2012-11-14 08:21:42
【问题描述】:

我正在尝试做一个简单的方法,如果文件的上层目录为空,则删除它的上层目录,直到它到达基目录,但我无法使其工作。

它会删除文件及其父目录,但不会删除其下一个父目录,因为它会抛出 DirectoryNotEmptyException。它确实是空的,因为只有一个子目录,并且在上一次迭代中被删除。

所以,文件被删除了,它的父文件也被删除了,它停在那里,没有更多的上层目录被删除。

已编辑:(修改后的代码)

删除目录似乎有延迟,所以在下一次检查目录的空状态时,之前的还没有删除。所以我添加了一个while循环来检查直到目录不存在。我不知道这是否是一种糟糕的技术,但它可以满足我的需求。

public static void removeFileAndParentsIfEmpty(Path path) throws IOException {
    if(path == null || path.endsWith(FilesPath.BILLS_DIRECTORY)) {
        return;
    }
    if (Files.isRegularFile(path)){
        Files.deleteIfExists(path);
    } else if (Files.isDirectory(path)){
        if(path.toFile().list().length == 0){
            Files.delete(path);
            while(Files.exists(path));
        }else{
            return;
        }
    } else {
        return;
    }
    removeFileAndParentsIfEmpty(path.getParent());
}

如果有人能给出更好的解决方案,这个问题仍然有待批准。 谢谢。

【问题讨论】:

  • 抛出异常时方法是否停止,我的意思是,如果 Files.delete() 抛出 DirectoryNotEmptyException,它会被捕获并且方法结束而不进行另一个递归调用,还是我错了?
  • 哦,抱歉,错过了重新通话,我的错:P

标签: java java-7 java-io


【解决方案1】:

您没有空目录的基本条件,因此在第二次遍历您的递归函数时,它会尝试在目录本身之前删除空目录父级。一个简单的代码更改应该足以解决这个问题:

public static void removeFileAndParentsIfEmpty(Path path)
        throws IOException {
    if(path == null || path.endsWith(BASEPATH)) return;

    if (Files.isRegularFile(path)) {
        Files.deleteIfExists(path);
    } else if(Files.isDirectory(path)) {
        try {
            Files.delete(path);
        } catch(DirectoryNotEmptyException e) {
            return;
        }
    }

    removeFileAndParentsIfEmpty(path.getParent());
}

【讨论】:

  • 它应该像那样工作,但它没有。好像 Files.delete() 并没有立即删除目录,当在下一次递归调用中再次调用时,之前的目录仍然没有被删除,这可能吗?
  • 我不得不做一个有效的小技巧,但我认为这不是一个很好的用途。删除目录后,只需调用:'while(Files.exists(path));' 将等到目录不存在并继续递归遍历。
【解决方案2】:

我建议你的问题在这里

Files.delete(path.getParent());
removeFileAndParentsIfEmpty(path.getParent());

您删除父文件夹,再次调用您的方法以尝试删除同一个文件夹...看到它不再存在,第二次调用只是失败并存在而不做任何事情。

我还会添加一个签入以查看目录是否为空,但你是对的,异常会捕获它,我只是认为这是一种不好的做法,并且你正在寻找的条件异常 -恕我直言

【讨论】:

  • 我会调查的。如果您说这不是一个好习惯,我相信您,谢谢您的建议。我只是想保存代码。
  • 恕我直言,例外是“意外”情况,您正在预料这种情况,因此它不是“意外”。 Java 有时可能会抛出很多异常,但是在过去几年中使用基于 C 的系统,我更喜欢异常而不是错误级别和错误查找:P
  • 您能检查一下我对代码所做的修改并告诉我是否可以吗?谢谢!
  • 我不确定 while 循环是干什么用的,否则看起来还可以
  • while 循环是等待目录被删除,因为在下一次递归调用中前一个目录还没有被删除。
猜你喜欢
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多