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