如何在不删除父文件夹的情况下递归删除空目录



以下函数用于删除备份文件夹中的空目录。但这种方法的问题是,如果备份文件夹为空,它也会删除备份文件夹。

public static void deleteEmptyDirectoriesOfFolder(final File folder) {
if(folder.listFiles().length == 0){
folder.delete();
}else {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
deleteEmptyDirectoriesOfFolder(fileEntry);
if(fileEntry.listFiles().length == 0){
fileEntry.delete();
}
}
}
}
}

假设我的文件夹结构如下,

backup
-2019
-10
-15
-2020

如果我将方法调用为deleteEmptyDirectoriesOfFolder(backup),它也会删除backup文件夹。有没有建议在不包含第二个参数的情况下修复它?

您的距离如此之近,只需将其分为两种方法:

  • deleteEmptySubDirectoriesOfFolder为所有子目录调用当前方法
  • deleteEmptyDirectoriesOfFolder您当前的方法

这是一种新方法:

public static void 
deleteEmptySubDirectoriesOfFolder(final File folder) 
{
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
deleteEmptyDirectoriesOfFolder(fileEntry);
if(fileEntry.listFiles().length == 0){
fileEntry.delete();
}
}
}
}

有一个围绕File的包装器类,如下所示

class FileWrapper {
private File folder;
private boolean isRoot;
}

当您第一次调用deleteEmptyDirectoriesOfFolder时,将FileWrapper初始化为

File folder = new File("<backup_dir_path>");
FileWrapper fileWrapper = new FileWrapper(folder, true);
deleteEmptyDirectoriesOfFolder(fileWrapper);

然后将CCD_ 6方法略微更改为

public static void deleteEmptyDirectoriesOfFolder(final FileWrapper fileWrapper) {
if(fileWrapper.getFolder().listFiles().length == 0 && !fileWrapper.getIsRoot()){
fileWrapper.getFolder().delete();
}else {
for (final File fileEntry : fileWrapper.getFolder().listFiles()) {
if (fileEntry.isDirectory()) {
FileWrapper fileWrapper = new FileWrapper(fileEntry, false);
deleteEmptyDirectoriesOfFolder(fileWrapper);
if(fileEntry.listFiles().length == 0){
fileEntry.delete();
}
}
}
}
}

实际上。。。我很惊讶你从来没有得到一个NullPointerException。我认为你应该。根据您提供的目录结构示例,我将树解释为:

- backup
- 2019
- 10   
- 15
- 2020

deleteEmptyDirectoriesOfFolder((方法中的for循环遍历文件夹时,它会对由fileEntry.isDirectory((。递归调用最终到达名为15的子目录,在这种情况下进行最后的递归调用。在最后一次递归调用时,if语句在for循环之上的条件

if (folder.listFiles().length == 0) {
folder.delete();
}

变为true,最终子目录被删除,递归调用返回到上一次递归调用,除非现在,因为文件夹(15(被删除,fileEntry.listFiles()变为空,因此当再次检查fileEntry.listFiles()时(在递归调用下for循环内(:

deleteEmptyDirectoriesOfFolder(fileEntry);
if (fileEntry.listFiles().length == 0) { // HERE
fileEntry.delete();
}

应抛出NullPointerException。您想忽略那些为null的文件,因此,在尝试播放之前,您可能应该检查fileEntry.listFiles((是否为null,如下所示:

public static void deleteEmptyDirectoriesOfFolder(final File folder) {
if (folder.listFiles().length == 0) {
folder.delete();
}
else {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
deleteEmptyDirectoriesOfFolder(fileEntry);
if (fileEntry.listFiles() != null && fileEntry.listFiles().length == 0) {
fileEntry.delete();
}
}
}
}
}

如果您不想同时删除备份文件夹(如果该文件夹为空(,则只需使用for循环(backup目录应保留(:

public static void deleteEmptyDirectoriesOfFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
deleteEmptyDirectoriesOfFolder(fileEntry);
if (fileEntry.listFiles() != null && fileEntry.listFiles().length == 0) {
fileEntry.delete();
}
}
}
}

您的方法现在应该可以正常工作了。

这是我在了解其他答案后的解决方案,

public static void deleteEmptyDirectoriesOfFolder(final File folder) {
deleteEmptyDirectoriesOfFolder(folder, true);
}
private static void deleteEmptyDirectoriesOfFolder(final File folder, boolean isRoot) {
if(!isRoot && folder.listFiles().length == 0){
folder.delete();
}else {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
File parent = fileEntry.getParentFile();
deleteEmptyDirectoriesOfFolder(fileEntry,false);
if(!isRoot && parent != null && parent.listFiles().length == 0){
parent.delete();
}
}
}
}
}

最新更新