Java programming tutorial.

A directory is an organizational file system structure that contains files and other directories. Java provides a few ways to traverse a directory, depending on which version you are using, including:

  1. Using the listFiles() method of the File class
  2. Using a DirectoryStream in Java 7 and onwards
  3. Using the static Files.list() method in Java 8 and onwards
  4. Using the walk() method in Java 8 and onwards

This programming tutorial will demonstrate how to utilize each of the above techniques to navigate a directory structure in Java.

SEE: Top Java IDEs

The File listFiles() method in Java

listFiles() is an instance method of the java.io.File class. To use it, all developers need to do is instantiate a new File object by providing a path to the constructor and and then invoke listFiles() on it. listFiles() returns an array of File objects that programmers can then iterate over to obtain more information about individual files and/or perform operations on them. Here is a basic example that lists all of the files and directories in the Windows “C:\My Documents” folder:

package com.developer;

import java.io.File;

public class ListFilesExample {
  public static void main(String[] args) {
    // Store the name of files and directories
    // in an array of Files.
    // Don't forget to escape the backslash character!
    File[] files = new File("C:\\My Documents").listFiles();
    
    // Traverse through the files array
    for (File file : files) {
      // If a subdirectory is found,
      // print the name of the subdirectory
      if (file.isDirectory()) {
        System.out.println("Directory: " + file.getName());
      }
      else {
        // Print the file name
        System.out.println("File: " + file.getName());
      }
    }
  }
}

Here is a partial listing of the directories and files found:

Directory: AAMS
Directory: Addictive Drums
Directory: Angular
Directory: angular-starter
Directory: Any Video Converter
Directory: articles
File: Avatar - House Of Eternal Hunt - transposed.tg
File: Avatar - House Of Eternal Hunt.tg
File: Avatar - Legend Of The King.tg
Directory: bgfx

Recursive directory traversal in Java

Since we can test for directories, we can move our for loop into a separate method that we can invoke recursively to list the files of subdirectories as well as the one provided to our method, as shown in the follow Java code example:

package com.developer;

import java.io.File;

public class RecursiveListFilesExample {
	
  public static void main(String[] args) {
    listFilesInDirectory(new File("C:\\My Documents"));
  }
  
  private static void listFilesInDirectory(File dirPath) {
    File filesList[] = dirPath.listFiles();
    
    // Traverse through the files array
    for (File file : filesList) {
      // If a sub directory is found,
      // print the name of the sub directory
      if (file.isDirectory()) {
        System.out.println("Directory: " + file.getName());
        listFilesInDirectory(file);
      }
      else {
        // Print the file name present in given path
        System.out.println("File: " + file.getName());
      }
    }
  }
}

We can see in the program output that it is now listing the files of subdirectories as well:

Directory: AAMS
File: AAMS V3 Manual.pdf
File: AAMS V4 Setup.exe
File: AAMS.xml
File: Licence.txt
File: Version.txt
Directory: Addictive Drums
Directory: Settings
File: MidifileDatabaseCache.dat
File: Recent.dat

SEE: Top online Java courses to learn Java

Using DirectoryStream to loop through files with Java

Java 7 introduced an alternative to listFiles() called DirectoryStream. It works well with the for-each construct, allowing us to iterate over the contents of the directory instead of reading everything at once.

The example code below shows how to use Java’s DirectoryStream in a method to list the files of a directory:

public Set<String> listFilesUsingDirectoryStream(String dir) throws IOException {
  Set<String> fileSet = new HashSet<>();
  try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir))) {
    for (Path path : stream) {
      if (!Files.isDirectory(path)) {
        fileSet.add(path.getFileName()
          .toString());
      }
    }
  }
  return fileSet;
}

Above, we let Java handle the closing of the DirectoryStream resource through the try-with-resources construct. We can employ the static Files.isDirectory(path) method to filter out directories and return a Set of files in the folder.

Using the static Files.list() Method

Java 8 introduced a new list() method in java.nio.file.Files. The list method returns a lazily populated Stream of entries in the directory. As such, it is more efficient for processing large folders. Here is a method that returns a Set of file names:

public Set<String> listFilesUsingFilesList(String dir) throws IOException {
  try (Stream<Path> stream = Files.list(Paths.get(dir))) {
    return stream
      .filter(file -> !Files.isDirectory(file))
      .map(Path::getFileName)
      .map(Path::toString)
      .collect(Collectors.toSet());
  }
}

Although the above code might look similar to listFiles(), it is different in how developers obtain each file’s path.

Again, we created the stream using the try-with-resources construct to ensure that the directory resource is closed after reading the stream.

How to walk over directory contents in Java

The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner (meaning that it starts with the file/directory at the greatest depth). The following program prints the full file paths for the full file tree under “C:\My Documents”:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

class FilesWalkExample {

  public static void main(String[] args)
    throws IOException {
  
    // Create a try-catch block and
    // provide the directory path of local machine
    try (Stream<Path> filepath = Files.walk(Paths.get("C:\\My Documents"))) {
      // Print the entire path of directories and files
      filepath.forEach(System.out::println);
    }
    // Throw an if directory doesn't exists 
    catch (IOException e) {
      throw new IOException("Directory not found!");
    }
  }
}

The first few lines of output confirm that file traversal started the greatest depth:

I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page1.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page2.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\proxy\page3.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\readOnlyPage.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\rectangles.html
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\Redirect.aspx
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\Redirect.aspx.cs
I:\My Documents\Angular\my-app\node_modules\selenium-webdriver\lib\test\data\resultPage.html

We could include directories as well by removing the Files::isRegularFile filter condition.

Final thoughts on Directory Navigation in Java

Java provides a few ways to traverse a directory, depending on which version you are using. Although we covered the main ones, there are other ways to navigate directories in Java, especially since the Stream API was introduced in Java 8.

SEE: Maven build automation tool review