Если сортируемые файлы могут быть изменены или обновлены одновременно, сортировка выполняется:
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;
}
Оба эти решения создают временную структуру данных карты для сохранения постоянного времени последнего изменения для каждого файла в каталоге. Причина, по которой мы должны это сделать, заключается в том, что если ваши файлы обновляются или модифицируются во время выполнения сортировки, тогда ваш компаратор будет нарушать требование транзитивности общего контракта интерфейса компаратора, поскольку время последнего изменения может изменяться во время сравнения.
Если, с другой стороны, вы знаете, что файлы не будут обновляться или изменяться во время сортировки, вы можете получить практически любой другой ответ, представленный на этот вопрос, к которому я неравнодушен:
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)
.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());
}
}
Примечание: я знаю, что вы можете избежать преобразования в и из объектов File в приведенном выше примере, используя api Files :: getLastModifiedTime в операции отсортированного потока, однако тогда вам придется иметь дело с проверенными исключениями ввода-вывода внутри лямбды, что всегда является проблемой , Я бы сказал, что если производительность достаточно критична, чтобы перевод был неприемлемым, то я бы либо имел дело с проверенным IOException в лямбда-выражении, передав его как UncheckedIOException, либо я бы вообще отказался от файлов api и имел дело только с объектами File:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));