Proper way to find newest file in a directory I wanted to ask if this is a better way to find a latest file in given directory. This is my current approach:

import java.io.File;
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.ZoneId;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FilesOperations {

    public static void main(String[] args) throws IOException {

        Set&lt;Path&gt; pathSet = getFilesFromDirectory("C:some/path/");

        iteratePaths(pathSet);

        getLatestFile(pathSet);
    }

    public static Set&lt;Path&gt; getFilesFromDirectory(String directory) {

        Set&lt;Path&gt; pathSet = new HashSet&lt;&gt;();

        Pattern pattern = Pattern.compile("(test\\d-)(\\d{12})(\\.txt)");
        Path lookUpPath = Paths.get(directory);

        Stream&lt;Path&gt; stream = null;
        try {
            stream = Files.find(lookUpPath, 1, (path, basicFileAttributes) -&gt; {
                File file = path.toFile();
                return !file.isDirectory() &amp;&amp; pattern.matcher(file.getName()).matches();
            });

            stream.forEach(path -&gt; {
                pathSet.add(path);
            });

        } catch (IOException e) {
            e.printStackTrace();
        }

        stream.close();
        return pathSet;
    }

    public static void iteratePaths(Set&lt;Path&gt; pathSet) {
        pathSet.stream().forEach(path -&gt; {
            System.out.println(path);
        });
    }

    public static Path getLatestFile(Set&lt;Path&gt; pathSet) throws IOException {

        long fileTime = 0;
        Path pathToReturn = null;
        BasicFileAttributes attr = null;

        for (Path path : pathSet) {
            attr = getBasicFileAttributes(path);
            if (attr.creationTime().toMillis() &gt; fileTime) {
            fileTime = attr.creationTime().toMillis();
                pathToReturn = path;
            }
        }

        attr = getBasicFileAttributes(pathToReturn);
        System.out.println("Latest file: " + pathToReturn + " - " + attr.creationTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        return pathToReturn;
    }

    private static BasicFileAttributes getBasicFileAttributes(Path pathToReturn) throws IOException {
        BasicFileAttributes attr;
        attr = Files.readAttributes(pathToReturn, BasicFileAttributes.class);
        return attr;
    }

}


I know this is quite simple without any sophisticated solutions, but it works. I hope you can point some places for improvements. If you have some ideas, how to refactor code to use more streams, it would be great (e.g. in getLatestFile() ).
some minore issues only...

naming / return type

public static Path getLatestFile() assumes that you return only ONE file, but it's easily possible that you have two files of the same date... so you should maybe return a Set&lt;Path&gt; from your method getLatestFiles(). This method would return all files with the latest time stamp.

use a logging framework

you should write infos into a proper logging stream:

System.out.println("Latest file: " + pathToReturn + " - " + attr.creationTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());


note:

you could write the corresponding information directly inside the loop.  

for (Path path : pathSet) {
        attr = getBasicFileAttributes(path);
        if (attr.creationTime().toMillis() &gt; fileTime) {
        fileTime = attr.creationTime().toMillis();
            pathToReturn = path;
            //here
            System.out.println("Latest file: " + pathToReturn + " - " + attr.creationTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        }
    }

    //instead of here:
    //attr = getBasicFileAttributes(pathToReturn);
    //System.out.println("Latest file: " + pathToReturn + " - " + attr.creationTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());


more significant code (tell, don't ask):

maybe it's just my style but i would really directly return what is said:

private static BasicFileAttributes getBasicFileAttributes(Path pathToReturn) throws IOException {
    return Files.readAttributes(pathToReturn, BasicFileAttributes.class);
}


use a test case

instead of testing your code in a main-methode write a junit test. that makes the code clearer to read and you can get rid of the methods getFilesFromDirectory() and iteratePaths() which are only for testing.

ever since the test methods are still in review let me advise you about these:

possible NPE

it's possible to create a NullPointerException:

Stream&lt;Path&gt; stream = null;
try {...} catch (IOException e) {...}
//if an exception is raised within this block above an NPE will be thrown!
stream.close();


maybe you could consider a try-with-resources block? maybe you don't care because it's a mere test method, haha =)

use a Logger / Handle Exceptions

what do you do if an exception really happens? you should implement the actions that should happen in case of exception - not just printing to stacktrace:

Stream&lt;Path&gt; stream = null;
    try {...} catch (IOException e) {
        //don't print - take actions instead!
        //e.printStackTrace();
    }


as said above, maybe you don't care because it's a mere test method...