Find below a small snippet which does what you want to achieve.
For demonstration purpose it also generates some example directories and files.
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.util.Date;
import java.util.Optional;
import static java.util.concurrent.TimeUnit.MINUTES;
public class FindRecentFileRecursively {
public static void main(String[] args) throws IOException {
// create some dummy directories/files
Path root = Paths.get("/tmp/foobar");
for (char c="A"; c <= 'C'; c++) {
Path dir = root.resolve("dir_" + c);
System.out.println("create sample directory " + dir.toString());
Files.createDirectories(dir);
long now = System.currentTimeMillis();
for (int i = 1; i <= 3; i++) {
File file = dir.resolve("file" + i).toFile();
file.createNewFile();
file.setLastModified(now + MINUTES.toMillis(i));
printFileInfo(file);
}
}
System.out.println("list the most recent file per directory");
// find all directories below /tmp/foobar
Files.find(root, Integer.MAX_VALUE, (path, attrs) -> attrs.isDirectory())
// for each directory
.forEach((dir) -> {
try {
// find all contained files
Optional<Path> recentFile = Files.find(dir, 1,
(path, attrs) -> attrs.isRegularFile())
// return the file with the recent last
// modification time
.max((p1, p2)
-> Long.compare(
p1.toFile().lastModified(),
p2.toFile().lastModified()));
// if a file was found
if (recentFile.isPresent()) {
// print modification time and file name
printFileInfo(recentFile.get().toFile());
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
});
}
private static void printFileInfo(File file) {
System.out.printf(" mtime: %td.%<tm.%<tY %<tH:%<tM:%<tS file: %s%n",
new Date(file.lastModified()),
file.getAbsolutePath()
);
}
}
output like
create sample directory /tmp/foobar/dir_A
mtime: 05.01.2016 15:35:15 file: /tmp/foobar/dir_A/file1
mtime: 05.01.2016 15:36:15 file: /tmp/foobar/dir_A/file2
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_A/file3
create sample directory /tmp/foobar/dir_B
mtime: 05.01.2016 15:35:15 file: /tmp/foobar/dir_B/file1
mtime: 05.01.2016 15:36:15 file: /tmp/foobar/dir_B/file2
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_B/file3
create sample directory /tmp/foobar/dir_C
mtime: 05.01.2016 15:35:15 file: /tmp/foobar/dir_C/file1
mtime: 05.01.2016 15:36:15 file: /tmp/foobar/dir_C/file2
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_C/file3
list the most recent file per directory
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_A/file3
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_B/file3
mtime: 05.01.2016 15:37:15 file: /tmp/foobar/dir_C/file3
update To find the newest files per direct subdirectory of a given root the below snippet will do the work.
Assume a directory structure like
/tmp/foobar
/tmp/foobar/dir_A
/tmp/foobar/dir_A/sub_A
/tmp/foobar/dir_B
/tmp/foobar/dir_B/sub_B
/tmp/foobar/dir_C
/tmp/foobar/dir_C/sub_C
and you start with the root
directory as /tmp/foobar
the code will return the newest file in /tmp/foobar/dir_A
and below, in /tmp/foobar/dir_B
and below …
System.out.println("list the most recent file per direct subdirectory");
// find all direct directories below /tmp/foobar
Files.find(root, 1, (path, attrs) -> attrs.isDirectory())
// filter out the root itself
.filter(p -> !p.equals(root))
.forEach((dir) -> {
try {
// find all contained files in any subdirectory
Optional<Path> recentFile = Files.find(dir, Integer.MAX_VALUE,
(path, attrs) -> attrs.isRegularFile())
// return the file with the recent last
// modification time
.max((p1, p2)
-> Long.compare(p1.toFile().lastModified(),
p2.toFile().lastModified()));
// if a file was found
if (recentFile.isPresent()) {
// print modification time and file name
printFileInfo(recentFile.get().toFile());
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
});
output
mtime: 08.01.2016 13:10:57 file: r:\temp\foobar\dir_A\sub_A\file1
mtime: 08.01.2016 13:11:39 file: r:\temp\foobar\dir_B\sub_B\file3
mtime: 08.01.2016 13:11:19 file: r:\temp\foobar\dir_C\file1
edit Following snippet also works with Java 6.
File root = new File("/tmp/foobar");
File[] topDirectories = root.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
System.out.println("topDirectories = " + Arrays.toString(topDirectories));
for (File directory : topDirectories) {
File recentFile = new File("");
recentFile.setLastModified(0L);
recentFile = getRecentFile(directory, recentFile);
System.out.println("recentFile = " + recentFile);
}
.
// if you have a huge amount of files in deeply nested directories
// this might need some further tuning
static File getRecentFile(File dir, File baseFile) {
File recentFile = baseFile;
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
recentFile = getRecentFile(file, recentFile);
} else {
if (file.lastModified() > recentFile.lastModified()) {
recentFile = file;
}
}
}
return recentFile;
}
11
solved Get latest file directory wise in java