-1

Scenario:

Path: /users/country/CAN/DateFolder1 more directories /users/country/CAN/DateFolder2 /users/country/CAN/DateFolder3

DateFolder1 and DateFolder2 are empty.

I want to delete datefolder when they are empty, but i can't mention the datefolder name exclusively

using below, i am able to delete directory till the path i mention, but need logic to search. for inner directories only after the specified path.

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

2 Answers2

0

To delete empty folders inside /users/country/CAN without recurcy:

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();
            }
        }
    }
}

Update. For example root folder is /users/country and we need to remove all empty folders at a certain depth from root. In case from your comment depth=2. I used most simple IO as task is simple. If you want NIO you can find about 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);
                }
            }
        }
    }
}

Update 2. Example with 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();
            }
        }
    });
}
0

Update: Below answer was updated to reflect what was expected.

I was also thinking of the Java NIO API but there's already an accepted answer, nevertheless here is an API using Java NIO

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;
    }
}

Before:

Before Run

Output:

Output

After:

After

comdotlinux
  • 143
  • 2
  • 9
  • I need result as following: current: /tmp/1 ->one -> folder(empty) ->two ->folder(empty) ->three -> folder -> file ->four -> folder ->file After: /tmp/1 ->one ->two ->three -> folder -> file ->four -> folder ->file so basically i don't want folder one, two, three four to be deleted ever, only sub folder inside it when they are empty – amandeep gandhi Mar 24 '21 at 21:50
  • The answer is updated, should do what you wanted to do. – comdotlinux Mar 26 '21 at 09:23