13

Considering there is the "new" streams API in Java 8 I can use Files.walk to iterate over a folder. How can I only get the child folders of my given directory if using this method or maybe depth=2?

I currently have this working example, which sadly also prints the root path as all "subfolders".

Files.walk(Paths.get("/path/to/stuff/"))
     .forEach(f -> {
        if (Files.isDirectory(f)) {
            System.out.println(f.getName());
        }
     });

I therefore reverted to the following approach. Which stores the folders in memory and needs handling of the stored list afterwards, which I would avoid and use lambdas instead.

File[] directories = new File("/your/path/").listFiles(File::isDirectory);
lony
  • 6,733
  • 11
  • 60
  • 92
  • May be count the number of backslash in the path in foreach loop and whatever having the depth as required can be filtered out – Aman Chhabra Jul 26 '18 at 06:49
  • You could probably use [Files.walk with maxDepth](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#walk-java.nio.file.Path-int-java.nio.file.FileVisitOption...-) or [Files.walkTree with maxDepth](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#walkFileTree-java.nio.file.Path-java.util.Set-int-java.nio.file.FileVisitor-) – Lino Jul 26 '18 at 06:55

6 Answers6

16

To list only sub-directories of a given directory:

Path dir = Paths.get("/path/to/stuff/");
Files.walk(dir, 1)
     .filter(p -> Files.isDirectory(p) && ! p.equals(dir))
     .forEach(p -> System.out.println(p.getFileName()));
Andreas
  • 154,647
  • 11
  • 152
  • 247
16

Here is a solution that works with arbitrary minDepth and maxDepth also larger than 1. Assuming minDepth >= 0 and minDepth <= maxDepth:

final int minDepth = 2;
final int maxDepth = 3;
final Path rootPath = Paths.get("/path/to/stuff/");
final int rootPathDepth = rootPath.getNameCount();
Files.walk(rootPath, maxDepth)
        .filter(e -> e.toFile().isDirectory())
        .filter(e -> e.getNameCount() - rootPathDepth >= minDepth)
        .forEach(System.out::println);

To accomplish what you asked originally in the question of listing "...only folders of certain depth...", just make sure minDepth == maxDepth.

L. Holanda
  • 4,432
  • 1
  • 36
  • 44
5

You can make use of the second overload of the Files#walk method to set the max depth explicitly. Skip the first element of the stream to ignore the root path, then you can filter only directories to finally print each one of them.

final Path root = Paths.get("<your root path here>");

final int maxDepth = <your max depth here>;

Files.walk(root, maxDepth)
    .skip(1)
    .filter(Files::isDirectory)
    .map(Path::getFileName)
    .forEach(System.out::println);
marsouf
  • 1,107
  • 8
  • 15
2
public List<String> listFilesInDirectory(String dir, int depth) throws IOException {
    try (Stream<Path> stream = Files.walk(Paths.get(dir), depth)) {
        return stream
                .filter(file -> !Files.isDirectory(file))
                .map(Path::getFileName)
                .map(Path::toString)
                .collect(Collectors.toList());
    }
}
  • Welcome to Stack Overflow! Your answer would be considerably better if you were to add some explanatory text, as to how your code fixes the OP's problem(s). – Adrian Mole Feb 12 '20 at 13:50
0

You can also try with this:

private File getSubdirectory(File file){
    try {
        return new File(file.getAbsolutePath().substring(file.getParent().length()));
    }catch (Exception ex){

    }
    return null;
}

collect file:

File[] directories = Arrays.stream(new File("/path/to/stuff")
          .listFiles(File::isDirectory)).map(Main::getSubdirectory)
                                        .toArray(File[]::new);
GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39
0

Agree with Andreas‘s answer,u can also use Files.list instead of Files.walk

Files.list(Paths.get("/path/to/stuff/"))
.filter(p -> Files.isDirectory(p) && ! p.equals(dir))
.forEach(p -> System.out.println(p.getFileName()));
kira
  • 15
  • 1
  • 1
    `Files.list` is not recursive so you're basically limited to the depth of 1 only. Does not answer the original question of "*only folders of **certain** depth*". – L. Holanda Apr 05 '19 at 18:43