Recursively list files in Java
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Recursively listing files means walking a directory tree and visiting every nested file under a starting path. In Java, the modern solution is almost always in java.nio.file, not java.io.File, because the newer API gives you better error handling, symbolic-link control, and clearer traversal logic. The older recursive File pattern still works, but it is usually a compatibility choice rather than the best one for new code.
The simplest modern approach is Files.walk
If you just want every file path under a directory, Files.walk is the shortest readable solution. It returns a stream of paths that already includes recursive traversal.
This is a good default for small utilities and reporting tasks. The try block is important because the stream holds filesystem resources that should be closed promptly.
Use walkFileTree when you need control
Files.walk is concise, but Files.walkFileTree is the better tool when you need custom behavior for errors, symbolic links, or per-directory hooks. It uses the visitor pattern, which is more verbose but more explicit.
This style is especially useful for production code because you can decide how to handle unreadable directories instead of failing the whole traversal.
The older File recursion still works
If you are working in a legacy codebase, you may still see a direct recursive method based on java.io.File.
It is easy to understand, but it gives you less control, less metadata, and weaker error reporting than the NIO API. For new code, Path and Files are usually the better choice.
Filter while traversing
Most real programs do not want every file. They want Java source files, image files, or files newer than a certain date. Both Files.walk and walkFileTree let you apply that filter naturally.
Keeping the filter close to the traversal makes the intent obvious and avoids collecting unnecessary paths into memory.
Common Pitfalls
One common mistake is forgetting to close the stream returned by Files.walk. Use a try block so directory handles are released properly.
Another issue is following symbolic links without thinking through cycles. If your directory tree can contain links back into earlier folders, you need to decide whether link-following is safe.
Developers also assume listFiles() always returns an array. It can return null when the directory is unreadable or invalid, so legacy recursion code must check for that.
Finally, avoid loading every path into a list unless you really need all of them at once. Streaming the traversal is usually more memory-friendly.
Summary
- For new Java code, prefer
Files.walkorFiles.walkFileTreeoverjava.io.File. - '
Files.walkis concise and works well for straightforward recursive listing.' - '
walkFileTreeis better when you need custom error handling or traversal rules.' - Use filters during traversal so you only process the files you actually need.
- Close streams and think about permissions and symbolic links in real-world code.
Related reading
- Recursively print all permutations of a string Javascript
- Red-black tree over AVL tree
- Red-Black Trees
- Red eye reduction algorithm
- Redeploy alternatives to JRebel
- Redeploy spring-boot application in docker container?
- Reducing the time complexity of this algorithm
- Redundancy algorithm for reading noisy bitstream

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.