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)) {
//...
}
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.favtuts.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 FindFileByExtension {
public static void main(String[] args) {
try {
List<String> files = findFiles(Paths.get("/home/tvt/workspace/favtuts"), "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
/home/tvt/workspace/favtuts/data/resize-default.png
/home/tvt/workspace/favtuts/google.png
/home/tvt/workspace/favtuts/folder/logo-new.png
2. Find files with multiple file extensions
This example finds files matched with multiple file extensions (.png, .jpg, .gif).
FindFileByExtension2.java
package com.favtuts.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 FindFileByExtension {
public static void main(String[] args) {
try {
String[] fileExtensions = {"png", "jpg", "gif"};
List<String> files = findFiles(Paths.get(folderName), fileExtensions);
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)) {
try (Stream<Path> walk = Files.walk(path)) {
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;
//System.out.println("Checking " + file + " ...");
for (String fileExtension : fileExtensions) {
if (file.endsWith(fileExtension)) {
result = true;
break;
}
}
return result;
}
}
Output
/home/tvt/workspace/favtuts/data/resize-fast.gif
/home/tvt/workspace/favtuts/data/resize-default.png
/home/tvt/workspace/favtuts/google.png
/home/tvt/workspace/favtuts/folder/favtuts-banner.jpg
/home/tvt/workspace/favtuts/folder/java.gif
/home/tvt/workspace/favtuts/folder/logo-new.png
/home/tvt/workspace/favtuts/google.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 “favtuts”.
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("favtuts"))
.collect(Collectors.toList());
}
Download Source Code
$ git clone https://github.com/favtuts/java-core-tutorials-examples
$ cd java-io/howto