Jeśli sortowane pliki można modyfikować lub aktualizować w tym samym czasie, sortowanie jest wykonywane:
Java 8+
private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
return fileStream
.map(Path::toFile)
.collect(Collectors.toMap(Function.identity(), File::lastModified))
.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
// .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) // replace the previous line with this line if you would prefer files listed newest first
.map(Map.Entry::getKey)
.map(File::toPath) // remove this line if you would rather work with a List<File> instead of List<Path>
.collect(Collectors.toList());
}
}
Java 7
private static List<File> listFilesOldestFirst(final String directoryPath) throws IOException {
final List<File> files = Arrays.asList(new File(directoryPath).listFiles());
final Map<File, Long> constantLastModifiedTimes = new HashMap<File,Long>();
for (final File f : files) {
constantLastModifiedTimes.put(f, f.lastModified());
}
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(final File f1, final File f2) {
return constantLastModifiedTimes.get(f1).compareTo(constantLastModifiedTimes.get(f2));
}
});
return files;
}
Oba te rozwiązania tworzą tymczasową strukturę danych mapy, aby zaoszczędzić stały czas ostatniej modyfikacji każdego pliku w katalogu. Powodem, dla którego musimy to zrobić, jest to, że jeśli twoje pliki są aktualizowane lub modyfikowane podczas sortowania, twój komparator naruszy wymagania dotyczące przechodniości umowy generalnej interfejsu komparatora, ponieważ czasy ostatniej modyfikacji mogą się zmieniać podczas porównania.
Jeśli z drugiej strony wiesz, że pliki nie zostaną zaktualizowane lub zmodyfikowane podczas sortowania, możesz uciec od prawie każdej innej odpowiedzi przesłanej na to pytanie, której częściowo jestem zdania:
Java 8+ (bez jednoczesnych modyfikacji podczas sortowania)
private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
return fileStream
.map(Path::toFile)
.sorted(Comparator.comparing(File::lastModified))
.map(File::toPath) // remove this line if you would rather work with a List<File> instead of List<Path>
.collect(Collectors.toList());
}
}
Uwaga: Wiem, że możesz uniknąć tłumaczenia na i z obiektów File w powyższym przykładzie, używając Files :: getLastModifiedTime api w posortowanym strumieniu, jednak musisz poradzić sobie ze sprawdzonymi wyjątkami IO wewnątrz lambda, co zawsze jest uciążliwe . Powiedziałbym, że jeśli wydajność jest na tyle krytyczna, że tłumaczenie jest niedopuszczalne, wówczas albo poradziłbym sobie ze sprawdzonym wyjątkiem IOException w lambda, propagując go jako UncheckedIOException, albo całkowicie zrezygnowałem z interfejsu API plików i zajmowałem się tylko obiektami File:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));