Java IO Tutorial

Java Files.find examples

The Files.find API is available since Java 8. It searches or finds files from a file tree quickly.

Topics

  1. Files.find() method signature
  2. Find files by filename
  3. Find files by file size
  4. 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.

Files.java

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 put 1, which means the search for top-level or root folder only, ignore all its subfolders; If we want to search for all folder levels, put Integer.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 put FileVisitOption.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.

FileFindExample1.java

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.

FileFindExample1.java

  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.

FileFindExample2.java

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.

Terminal

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.

FileFindExample3.java

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

Terminal

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

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
0 Comments
Inline Feedbacks
View all comments