In Java 7 with the new I/O APIs, is there an easy way to list a directory's content by last modified date? Basically I only need to get the file the wasn't modified for the longest time (sort by last modified ascending, take first filename).
-
Why is it marked as a duplicate? This question is about Java NIO. The other question has nothing about Java NIO. Not a duplicate. – Peter Aug 14 '20 at 22:58
6 Answers
There's no real "easy way" to do it, but it is possible:
List<Path> files = new ArrayList<>();
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for(Path p : stream) {
files.add(p);
}
}
Collections.sort(files, new Comparator<Path>() {
public int compare(Path o1, Path o2) {
try {
return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
} catch (IOException e) {
// handle exception
}
}
});
This will sort the files soonest modified files last. DirectoryStream
s do not iterate through subdirectories.

- 44,417
- 8
- 90
- 141
-
thank you for the complete solution. File.listFiles() might make your code shorter :-) – stefan.at.kotlin Sep 03 '12 at 21:05
-
1
-
ah ok, sorry, didn't notice that. I don't need NIO, I was just wondering if NIO would offer a easy solution ;-) – stefan.at.kotlin Sep 03 '12 at 21:21
-
2Be aware, that the precision of lastModifiedTime might not be enough to compare the files. For example when copying a bunch of files, all the destination files will end up having the same lastModifiedTime so one cannot sort them by it. This happens, because the precision of lastModifiedTime is often set only up to the second, but not up to the millisecond. – asmaier Nov 26 '13 at 09:54
-
@asmaier's comment about the precision of lastModifiedTime is important. For ordered, unique Collections like `TreeSet`, this bug can make `.add()` fail. – daveloyall Apr 03 '15 at 18:03
-
1`Collections.sort(files, Comparator.comparingLong(File::lastModified));` – Eugene Feb 27 '18 at 12:56
A slightly "stream"ier variation of the Jeffrey's answer, which some might find easier as well. Posting for completeness.
try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) {
StreamSupport.stream(files.spliterator(), false)
.sorted((o1, o2) -> {
try {
return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
} catch (IOException ex) {
...
}
})
.filter(file -> Files.isRegularFile(file))
.forEach(file -> {
});
}

- 26,450
- 5
- 63
- 71
-
-
@ok2c Very nice! Yet, `Call requires API level 24`. Are there any alternatives for APIs < 24? – Luis A. Florit Oct 05 '21 at 16:25
Use listFiles() on the directory's File object. Convert the array to an arraylist. Then sort them using a the static sort method on the Collections class with a custom Comparator that uses the getTotalSpace() method on the Files. EDIT: Use lastModified instead of getTotalSpace.

- 23
- 3
lastModified()
Returns the time that the file denoted by this abstract pathname was last modified.

- 2,510
- 1
- 16
- 27
-
Thank you, but out of a directory with like 100 files I need to get the oldest one, just wondering, if there is a better way than manually comparing all lastModified values, e.g. passing just a sorting option and then take the first or last entry of the list, depending on the sorting direction. – stefan.at.kotlin Sep 03 '12 at 20:59
-
In order to know which file is the newest/oldest it is necessary to loop over all the files. Which is what the (as of my knowledge) FileFilter does. The only thing except as mentioned in the jdevelop's post (EDIT: probably a lot of ways to achive this), would be to create a comparator as this `File f = new File(""); Arrays.sort(f.listFiles(), new Comparator
() { public int compare(File o1, File o2) { return (int)(o1.lastModified() - o2.lastModified()); } }); return f[0];` – atomman Sep 03 '12 at 21:07
you can use http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter) and supply http://docs.oracle.com/javase/1.5.0/docs/api/java/io/FileFilter.html
then compare http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified() and you're done
if you do care about performance - then simply take one with maximum/minimum value from the file list, that will give you O(n) complexity

- 12,176
- 10
- 56
- 112
Note: This solution requires Guava.
Java IO/NIO API provides low-level access to directory listings, but there is no processing done, which is left to the caller. The new Java7 NIO DirectoryStream has the minimal footprint when accessing the directory listing for further processing, e.g. sorting.
Here is my solution: Read files from DirectoryStream and build a sorted queue with (optionally) limited size from the stream. Return the oldest/newest elements from the queue.
private void listFilesOldestFirst(final File directory, final Integer maxNumberOfFiles) {
final Builder<File> builder =
MinMaxPriorityQueue
.orderedBy(LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
if( maxNumberOfFiles != null ) {
builder.maximumSize(maxNumberOfFiles);
}
// queue with constant space, if maxNumberOfFiles is set, otherwise behaves like an unbound queue with an O(log n) penalty for insertion
final MinMaxPriorityQueue<File> oldestFiles = builder.create();
try(DirectoryStream<Path> stream = Files.newDirectoryStream(directory.toPath())) {
for(final Path p : stream) {
oldestFiles.add(p.toFile());
}
} catch (final IOException e) {
throw new RuntimeException(e);
}
final File[] fileArray = oldestFiles.toArray(new File[]{});
Arrays.sort(fileArray, oldestFiles.comparator());
// ... use fileArray
final ArrayList<File> arrayList = Lists.newArrayList(oldestFiles);
Collections.sort(arrayList, oldestFiles.comparator());
// ... use arrayList
}
These dependencies are required for the Guava MinMaxPriorityQueue and the FileComparator:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
You may also find the filter parameter of Files.newDirectoryStream useful:
final Filter<Path> sampleFilter = new Filter<Path>() {
@Override
public boolean accept(final Path entry) throws IOException {
return true; // see commons-io -> FileFilterUtils
}
};
...
Files.newDirectoryStream(directory.toPath(), sampleFilter)

- 2,140
- 21
- 23

- 1,149
- 10
- 18