6

I'd like to write a function that deletes all empty folders, with the option to ignore certain file types (allowed file types are stored in the hashmap) and tell if it should look inside directories.

Calling:

HashMap<String, Boolean> allowedFileTypes = new HashMap<String, Boolean>();
allowedFileTypes.put("pdf", true);
deleteEmptyFolders("ABSOLUTE PATH", allowedFileTypes, true);

Function:

public static void deleteEmptyFolders(String folderPath, HashMap<String, Boolean> allowedFileTypes, boolean followDirectory) {

    File targetFolder = new File(folderPath);
    File[] allFiles = targetFolder.listFiles();


    if (allFiles.length == 0)
        targetFolder.delete();

    else {
        boolean importantFiles = false;

        for (File file : allFiles) {

            String fileType = "folder";
            if (!file.isDirectory())
                fileType = file.getName().substring(file.getName().lastIndexOf('.') + 1);

            if (!importantFiles)
                importantFiles = (allowedFileTypes.get(fileType) != null);

            if (file.isDirectory() && followDirectory)
                deleteEmptyFolders(file.getAbsolutePath(), allowedFileTypes, followDirectory);
        }

        // if there are no important files in the target folder
        if (!importantFiles)
            targetFolder.delete();
    }
}

The problem is that nothing is happening, even though it looks through all folders till the end. Is this a good approach or am I missing something completely?

TomTom
  • 2,820
  • 4
  • 28
  • 46
  • Any reason you're using a HashMap instead of a HashSet? – aioobe Sep 24 '14 at 13:00
  • @aioobe Now that you mention it. No.. I will make it a set, because I will only check if it nulls. Thanks. – TomTom Sep 24 '14 at 13:03
  • 1
    Maybe this can help you a bit: http://stackoverflow.com/a/20281958/2496309 – Michał Urbaniak Sep 24 '14 at 13:04
  • @Mikrobus You are right that was it. You have to delete all files before you can delete a folder. Also sometimes there are hidden config files in the folders, that can be tricky. Thanks you could post it as an answer. – TomTom Sep 24 '14 at 13:14
  • @aioobe Thanks for your support. I already solved the problem. – TomTom Sep 24 '14 at 13:15

5 Answers5

7

This piece of code recursively delete all the empty folders or directory:

public class DeleteEmptyDir {
private static final String FOLDER_LOCATION = "E:\\TEST";
private static boolean isFinished = false;

public static void main(String[] args) {

    do {
        isFinished = true;
        replaceText(FOLDER_LOCATION);
    } while (!isFinished);
}

private static void replaceText(String fileLocation) {
    File folder = new File(fileLocation);
    File[] listofFiles = folder.listFiles();
    if (listofFiles.length == 0) {
        System.out.println("Folder Name :: " + folder.getAbsolutePath() + " is deleted.");
        folder.delete();
        isFinished = false;
    } else {
        for (int j = 0; j < listofFiles.length; j++) {
            File file = listofFiles[j];
            if (file.isDirectory()) {
                replaceText(file.getAbsolutePath());
            }
        }
    }
}
}
CinCout
  • 9,486
  • 12
  • 49
  • 67
Arijit Paul
  • 71
  • 1
  • 2
1

You can use code to delete empty folders using Java.

public static long deleteFolder(String dir) {

        File f = new File(dir);
        String listFiles[] = f.list();
        long totalSize = 0;
        for (String file : listFiles) {

            File folder = new File(dir + "/" + file);
            if (folder.isDirectory()) {
                totalSize += deleteFolder(folder.getAbsolutePath());
            } else {
                totalSize += folder.length();
            }
        }

        if (totalSize ==0) {
            f.delete();
        }

        return totalSize;
    }
Rakesh Chaudhari
  • 3,310
  • 1
  • 27
  • 25
0

Shortest code I could come up with is following Java >=8 code:

        Files.walk(Paths.get("/my/base/dir/"))
                .sorted(Comparator.reverseOrder())
                .map(Path::toFile)
                .filter(File::isDirectory)
                .forEach(File::delete);

Add a second (or more) filter statement with whatever clause you need to include/exclude certain folders. File::delete should not delete folders with contents. Use at own risk.

supernova
  • 1,762
  • 1
  • 14
  • 31
0

Kotlin:

fun deleteAllEmptyDirectories(rootPath: Path): Collection<Path> =
    mutableListOf<Path>()
        .apply {
            Files.walk(testPath)
                .sorted { p1, p2 -> p2.count() - p1.count() }
                .map { it.toFile() }
                .filter { it.isDirectory }
                .forEach {
                    if (it.listFiles().all { el -> el.isDirectory && contains(el.toPath()) }) {
                        val path = it.toPath()
                        add(path)
                        Files.delete(path)
                    }
                }
        }

Test:

 private val testPath = Path.of("build", javaClass.simpleName, UUID.randomUUID().toString())

@Test
fun test() {
    Files.createDirectory(testPath)

    val dirWithTwoEmptySubdirs = Files.createDirectory(testPath.resolve("dirWithTwoEmptySubdirs"))
    val dir1 = Files.createDirectory(dirWithTwoEmptySubdirs.resolve("dir1"))
    val dir2 = Files.createDirectory(dirWithTwoEmptySubdirs.resolve("dir2"))
    val dirWithOneDiffDir = Files.createDirectory(testPath.resolve("dirWithOneDiffDir"))
    var emptyDir = Files.createDirectory(dirWithOneDiffDir.resolve("empty"))
    val notEmptyDir = Files.createDirectory(dirWithOneDiffDir.resolve("notempty"))
    Files.writeString(notEmptyDir.resolve("file.txt"), "asdf")

    assertEquals(
        setOf<Path>(dirWithTwoEmptySubdirs, dir1, dir2, emptyDir),
        deleteAllEmptyDirectories(testPath).toSet()
    )
}
typik89
  • 907
  • 1
  • 10
  • 23
0

After reading all answers and concluding that all of them have at least one problem I still had to write it myself:

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Temp {

  public static void main(String[] args) {
    final String path = "D:\\";
    deleteEmpty(new File(path));
  }

  private static int deleteEmpty(File file) {
    List<File> toBeDeleted = Arrays.stream(file.listFiles()).sorted() //
        .filter(File::isDirectory) //
        .filter(f -> f.listFiles().length == deleteEmpty(f)) //
        .collect(Collectors.toList());
    int size = toBeDeleted.size();
    toBeDeleted.forEach(t -> {
      final String path = t.getAbsolutePath();
      final boolean delete = t.delete();
      System.out.println("Deleting: \t" + delete + "\t" + path);
    });
    return size;
  }

}
Daan
  • 127
  • 4