Java Files.find examples
The Files.find
API is available since Java 8. It searches or finds files from a file tree quickly.
Topics
- Files.find() method signature
- Find files by filename
- Find files by file size
- Find files by last modified time
In the old days, we always use an error-prone recursive loop to walk a file tree. This Java 8 Files.find
can save you a lot of time.
1. Files.find() Signature
Review the Files.find()
signature.
public static Stream<Path> find(Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options)
throws IOException
- The
path
, starting file or folder. - The
maxDepth
defined the maximum number of directory levels to search. If we put1
, which means the search for top-level or root folder only, ignore all its subfolders; If we want to search for all folder levels, putInteger.MAX_VALUE
. - The
BiPredicate<Path, BasicFileAttributes>
is for condition checking or filtering. - The
FileVisitOption
tells if we want to follow symbolic links, default is no. We can putFileVisitOption.FOLLOW_LINKS
to follow symbolic links.
2. Find files by filename
This example uses Files.find()
to find files that matched filename google.png
, starting from the folder C:\\test
, and included all levels of its subfolders.
package com.mkyong.io.api;
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 FileFindExample1 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\test");
List<Path> result = findByFileName(path, "google.png");
result.forEach(x -> System.out.println(x));
}
public static List<Path> findByFileName(Path path, String fileName)
throws IOException {
List<Path> result;
try (Stream<Path> pathStream = Files.find(path,
Integer.MAX_VALUE,
(p, basicFileAttributes) ->
p.getFileName().toString().equalsIgnoreCase(fileName))
) {
result = pathStream.collect(Collectors.toList());
}
return result;
}
}
We also can use Files
APIs to check the path further.
try (Stream<Path> pathStream = Files.find(path,
Integer.MAX_VALUE,
(p, basicFileAttributes) ->{
// if directory or no-read permission, ignore
if(Files.isDirectory(p) || !Files.isReadable(p)){
return false;
}
return p.getFileName().toString().equalsIgnoreCase(fileName);
})
)
3. Find files by file size
This example uses Files.find()
to find files containing file size greater or equals 100MB.
package com.mkyong.io.api;
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 FileFindExample2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\Users\\mkyong\\Downloads");
long fileSize = 1024 * 1024 * 100; // 100M
List<Path> result = findByFileSize(path, fileSize);
for (Path p : result) {
System.out.println(String.format("%-40s [fileSize]: %,d", p, Files.size(p)));
}
}
public static List<Path> findByFileSize(Path path, long fileSize)
throws IOException {
List<Path> result;
try (Stream<Path> pathStream = Files.find(path,
Integer.MAX_VALUE,
(p, basicFileAttributes) -> {
try {
if (Files.isDirectory(p)) { // ignore directory
return false;
}
return Files.size(p) >= fileSize;
} catch (IOException e) {
System.err.println("Unable to get the file size of path : " + path);
}
return false;
}
)) {
result = pathStream.collect(Collectors.toList());
}
return result;
}
}
Output samples.
C:\Users\mkyong\Downloads\hello.mp4 [fileSize]: 4,796,543,886
C:\Users\mkyong\Downloads\java.mp4.bk [fileSize]: 5,502,785,778
C:\Users\mkyong\Downloads\ubuntu-20.04.1-desktop-amd64.iso [fileSize]: 2,785,017,856
#...
4. Find files by last modified time
This example uses File.find()
to find files containing last modified time equals or after yesterday.
package com.mkyong.io.api;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FileFindExample3 {
private static DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
public static void main(String[] args) throws IOException {
// find files, LastModifiedTime from yesterday and above
List<Path> result = findByLastModifiedTime(
Paths.get("C:\\test"),
Instant.now().minus(1, ChronoUnit.DAYS));
for (Path p : result) {
// formatting...
BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class);
FileTime time = attrs.lastModifiedTime();
LocalDateTime localDateTime = time.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
System.out.println(String.format("%-40s [%s]", p, localDateTime.format(DATE_FORMATTER)));
}
}
public static List<Path> findByLastModifiedTime(Path path, Instant instant)
throws IOException {
List<Path> result;
try (Stream<Path> pathStream = Files.find(path,
Integer.MAX_VALUE,
(p, basicFileAttributes) -> {
if(Files.isDirectory(p) || !Files.isReadable(p)){
return false;
}
FileTime fileTime = basicFileAttributes.lastModifiedTime();
// negative if less, positive if greater
// 1 means fileTime equals or after the provided instant argument
// -1 means fileTime before the provided instant argument
int i = fileTime.toInstant().compareTo(instant);
return i > 0;
}
)) {
result = pathStream.collect(Collectors.toList());
}
return result;
}
}
Output samples and assume today is 02/12/2020
C:\test\a.txt [02/12/2020 13:01:20]
C:\test\b.txt [01/12/2020 12:11:21]
#...
Download Source Code
$ git clone https://github.com/mkyong/core-java
$ cd java-io