Java IO Tutorial

How to find files with the file extension in Java

This article shows how to Java 8 Files.walk to walk a file tree and stream operation filter to find files that match a specific file extension from a folder and its subfolders.


  // find files matched `png` file extension from folder C:\\test
  try (Stream<Path> walk = Files.walk(Paths.get("C:\\test"))) {
      result = walk
              .filter(p -> !Files.isDirectory(p))   // not a directory
              .map(p -> p.toString().toLowerCase()) // convert path to string
              .filter(f -> f.endsWith("png"))       // check end with
              .collect(Collectors.toList());        // collect all matched to a List
  }

In the Files.walk method, the second argument, maxDepth defined the maximum number of directory levels to visit. And we can assign maxDepth = 1 to find files from the top-level folder only (exclude all its subfolders)


  try (Stream<Path> walk = Files.walk(Paths.get("C:\\test"), 1)) {
      //...
  }

Topics

  1. Find files with a specified file extension (Files.walk)
  2. Find files with multiples file extensions (Files.walk)

1. Find files with a specified file extension

This example finds files matched with png file extension. The finds start at the top-level folder C:\\test and included all levels of subfolders.

FindFileByExtension1.java

package com.mkyong.io.howto;

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

public class FindFileByExtension1 {

    public static void main(String[] args) {

        try {

            List<String> files = findFiles(Paths.get("C:\\test"), "png");
            files.forEach(x -> System.out.println(x));

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static List<String> findFiles(Path path, String fileExtension)
        throws IOException {

        if (!Files.isDirectory(path)) {
            throw new IllegalArgumentException("Path must be a directory!");
        }

        List<String> result;

        try (Stream<Path> walk = Files.walk(path)) {
            result = walk
                    .filter(p -> !Files.isDirectory(p))
                    // this is a path, not string,
                    // this only test if path end with a certain path
                    //.filter(p -> p.endsWith(fileExtension))
                    // convert path to string first
                    .map(p -> p.toString().toLowerCase())
                    .filter(f -> f.endsWith(fileExtension))
                    .collect(Collectors.toList());
        }

        return result;
    }

}

Output

Terminal

c:\test\bk\logo-new.png
c:\test\bk\resize-default.png
c:\test\google.png
c:\test\test1\test2\java.png
...

2. Find files with multiple file extensions

This example finds files matched with multiple file extensions (.png, .jpg, .gif).

FindFileByExtension2.java

package com.mkyong.io.howto;

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

public class FindFileByExtension2 {

    public static void main(String[] args) {

        try {

            String[] extensions = {"png", "jpg", "gif"};
            List<String> files = findFiles(Paths.get("C:\\test"), extensions);
            files.forEach(x -> System.out.println(x));

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static List<String> findFiles(Path path, String[] fileExtensions) throws IOException {

        if (!Files.isDirectory(path)) {
            throw new IllegalArgumentException("Path must be a directory!");
        }

        List<String> result;
        try (Stream<Path> walk = Files.walk(path, 1)) {
            result = walk
                    .filter(p -> !Files.isDirectory(p))
                    // convert path to string
                    .map(p -> p.toString().toLowerCase())
                    .filter(f -> isEndWith(f, fileExtensions))
                    .collect(Collectors.toList());
        }
        return result;

    }

    private static boolean isEndWith(String file, String[] fileExtensions) {
        boolean result = false;
        for (String fileExtension : fileExtensions) {
            if (file.endsWith(fileExtension)) {
                result = true;
                break;
            }
        }
        return result;
    }

}

Output

Terminal

c:\test\bk\logo-new.png
c:\test\bk\resize-default.gif
c:\test\bk\resize-fast.gif
c:\test\bk\resize.png
c:\test\google.jpg
c:\test\google.png
c:\test\test1\test2\java.png
c:\test\test1\test2\java.jpg

2.2 The isEndWith() method can be shorter with Java 8 stream anyMatch.


private static boolean isEndWith(String file, String[] fileExtensions) {

    // Java 8, try this
    boolean result = Arrays.stream(fileExtensions).anyMatch(file::endsWith);
    return result;

    // old school style
    /*boolean result = false;
    for (String fileExtension : fileExtensions) {
        if (file.endsWith(fileExtension)) {
            result = true;
            break;
        }
    }
    return result;*/
}

2.3 We also can remove the isEndWith() method and puts the anyMatch into the filter directly.


  public static List<String> findFiles(Path path, String[] fileExtensions)
      throws IOException {

      if (!Files.isDirectory(path)) {
          throw new IllegalArgumentException("Path must be a directory!");
      }

      List<String> result;
      try (Stream<Path> walk = Files.walk(path, 1)) {
          result = walk
                  .filter(p -> !Files.isDirectory(p))
                  // convert path to string
                  .map(p -> p.toString().toLowerCase())
                  //.filter(f -> isEndWith(f, fileExtensions))

                  // lambda
                  //.filter(f -> Arrays.stream(fileExtensions).anyMatch(ext -> f.endsWith(ext)))

                  // method reference
                  .filter(f -> Arrays.stream(fileExtensions).anyMatch(f::endsWith))     
                  .collect(Collectors.toList());
      }
      return result;

  }

2.4 We can further enhance the program by passing different conditions into the stream filter; Now, the program can easily search or find files with a specified pattern from a folder. For examples:

Find files with filename starts with "abc".


  List<String> result;
  try (Stream<Path> walk = Files.walk(path)) {
      result = walk
              .filter(p -> !Files.isDirectory(p))
              // convert path to string
              .map(p -> p.toString())
              .filter(f -> f.startsWith("abc"))
              .collect(Collectors.toList());
  }

Find files with filename containing the words "mkyong".


  List<String> result;
  try (Stream<Path> walk = Files.walk(path)) {
      result = walk
              .filter(p -> !Files.isDirectory(p))
              // convert path to string
              .map(p -> p.toString())
              .filter(f -> f.contains("mkyong"))
              .collect(Collectors.toList());
  }

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-io

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Andrey
2 years ago

Thank you very much mkyong! You are building towers for fast learning and deeping to Java! Your posts really help me)

Ravi
3 years ago

Is there any limit to Collectors.collect method, as it’s not showing the complete file list in the directory is 40 files