Without any kind of filter, we can easily loop a folder's content (one level deep) via the Files.newDirectoryStream(Path dir) method. This method returns a DirectoryStream<Path>, which is an object that we can use to iterate over the entries in a directory:
Path path = Paths.get("D:/learning/books/spring");
try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
for (Path file: ds) {
System.out.println(file.getFileName());
}
}
If we want to enrich this snippet of code with a filter, then we have at least two solutions. One solution relies on another flavor of the newDirectoryStream() method, newDirectoryStream​(Path dir, String glob). Besides Path, this method receives a filter by using the glob syntax. For example, we can filter the D:/learning/books/spring folder for files that are of the PNG, JPG, and BMP types:
try (DirectoryStream<Path> ds =
Files.newDirectoryStream(path, "*.{png,jpg,bmp}")) {
for (Path file: ds) {
System.out.println(file.getFileName());
}
}
When glob syntax cannot help us anymore, it's time to use another flavor of newDirectoryStream() that gets a Filter, that is, newDirectoryStream​(Path dir, DirectoryStream.Filter<? super Path> filter). First, let's define a filter for files larger than 10 MB:
DirectoryStream.Filter<Path> sizeFilter
= new DirectoryStream.Filter<>() {
@Override
public boolean accept(Path path) throws IOException {
return (Files.size(path) > 1024 * 1024 * 10);
}
};
We can also do this in functional-style:
DirectoryStream.Filter<Path> sizeFilter
= p -> (Files.size(p) > 1024 * 1024 * 10);
Now, we can apply this filter like so:
try (DirectoryStream<Path> ds =
Files.newDirectoryStream(path, sizeFilter)) {
for (Path file: ds) {
System.out.println(file.getFileName() + " " +
Files.readAttributes(file, BasicFileAttributes.class).size()
+ " bytes");
}
}
Let's check out a few more filters that we can use with this technique:
- The following is a user-defined filter for folders:
DirectoryStream.Filter<Path> folderFilter
= new DirectoryStream.Filter<>() {
@Override
public boolean accept(Path path) throws IOException {
return (Files.isDirectory(path, NOFOLLOW_LINKS));
}
};
- The following is a user-defined filter for files that have been modified today:
DirectoryStream.Filter<Path> todayFilter
= new DirectoryStream.Filter<>() {
@Override
public boolean accept(Path path) throws IOException {
FileTime lastModified = Files.readAttributes(path,
BasicFileAttributes.class).lastModifiedTime();
LocalDate lastModifiedDate = lastModified.toInstant()
.atOffset(ZoneOffset.UTC).toLocalDate();
LocalDate todayDate = Instant.now()
.atOffset(ZoneOffset.UTC).toLocalDate();
return lastModifiedDate.equals(todayDate);
}
};
- The following is a user-defined filter for hidden files/folders:
DirectoryStream.Filter<Path> hiddenFilter
= new DirectoryStream.Filter<>() {
@Override
public boolean accept(Path path) throws IOException {
return (Files.isHidden(path));
}
};
In the following sections, we'll take a look at the different ways we can filter a file.