List Files in a Directory in Java
Problem
A directory holds entries that are either files or subdirectories; listing it returns its direct children, while walking it descends into every subfolder.
Create a small folder with two files and a subfolder, then list its direct contents in alphabetical order, labelling each entry.
Java Program
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.stream.Stream;
public class ListFilesInDirectory {
public static void main(String[] args) throws IOException {
Path dir = Paths.get("demo-folder");
Files.createDirectories(dir.resolve("images")); // a subfolder
Files.writeString(dir.resolve("readme.md"), "# Demo");
Files.writeString(dir.resolve("data.csv"), "id,name");
Files.writeString(dir.resolve("images").resolve("logo.png"), "png");
try (Stream<Path> entries = Files.list(dir)) { // direct children only
entries.sorted() // listing order isn't guaranteed, so sort it
.forEach(p -> System.out.println((Files.isDirectory(p) ? "[dir] " : "[file] ") + p.getFileName()));
}
deleteTree(dir);
}
static void deleteTree(Path dir) throws IOException {
try (Stream<Path> all = Files.walk(dir)) {
all.sorted(Comparator.reverseOrder()) // children before their parent folder
.forEach(p -> p.toFile().delete());
}
}
}Output
Core Logic
Files.list streams the folder's direct entries; sorting them makes the output predictable, since the file system returns them in no guaranteed order.
- 1
createDirectoriesandwriteStringbuild a sample folder to list. - 2
Files.list(dir)opens a stream of paths in try-with-resources. - 3
sorted()orders the paths alphabetically, and each is labelled[dir]or[file]. - 4
deleteTreeremoves everything afterwards, deleting children before their parent folder.
logo.png sits inside images/, so it doesn't appear — Files.list only goes one level deep.Key Point: Deleting a folder that still has contents fails, which is why the cleanup sorts paths in reverse order before deleting.
Key Concepts
Approach 2: Recursive Listing with Files.walk()
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.stream.Stream;
public class ListFilesRecursive {
public static void main(String[] args) throws IOException {
Path dir = Paths.get("demo-folder");
Files.createDirectories(dir.resolve("images"));
Files.writeString(dir.resolve("readme.md"), "# Demo");
Files.writeString(dir.resolve("data.csv"), "id,name");
Files.writeString(dir.resolve("images").resolve("logo.png"), "png");
try (Stream<Path> all = Files.walk(dir)) { // every level, starting with dir itself
all.filter(Files::isRegularFile)
.map(p -> dir.relativize(p).toString().replace('\\', '/')) // same separator on every OS
.sorted()
.forEach(System.out::println);
}
try (Stream<Path> all = Files.walk(dir)) {
all.sorted(Comparator.reverseOrder()).forEach(p -> p.toFile().delete());
}
}
}
Output
Core Logic
Files.walk visits the folder and everything beneath it, so nested files are included.
- 1
Files.walk(dir)streams every path at every depth. - 2
filter(Files::isRegularFile)keeps files and drops folders. - 3
dir.relativize(p)shows each path relative to the folder, with/as the separator on every OS.
images/logo.png now appears alongside the two top-level files.Key Point: Pass a depth limit, as in Files.walk(dir, 2), when scanning large directory trees, so the walk doesn't descend further than needed.
Key Concepts
Interview Questions
What's the difference between Files.list and Files.walk?
Files.list returns only the direct children of a folder, while Files.walk goes into every subfolder as well.
How do you list only files with a certain extension?
Filter by name: Files.list(dir).filter(p -> p.toString().endsWith(".txt")), or use Files.newDirectoryStream(dir, "*.txt").