Reputation: 7770
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);
Upvotes: 15
Views: 10768
Reputation: 41
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());
}
}
Upvotes: 2
Reputation: 4631
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
.
Upvotes: 18
Reputation: 1147
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);
Upvotes: 7
Reputation: 15
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()));
Upvotes: 0
Reputation: 9437
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);
Upvotes: 0
Reputation: 159096
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()));
Upvotes: 17