Si los archivos que está ordenando se pueden modificar o actualizar al mismo tiempo que se realiza la clasificación:
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;
}
Ambas soluciones crean una estructura de datos de mapa temporal para ahorrar un tiempo constante de última modificación para cada archivo en el directorio. La razón por la que debemos hacer esto es que si sus archivos se actualizan o modifican mientras se realiza su clasificación, su comparador violará el requisito de transitividad del contrato general de la interfaz del comparador porque los últimos tiempos modificados pueden estar cambiando durante la comparación.
Si, por otro lado, sabe que los archivos no se actualizarán o modificarán durante su ordenación, puede salirse con casi cualquier otra respuesta enviada a esta pregunta, de la cual estoy parcial a:
Java 8+ (sin modificaciones concurrentes durante la ordenación)
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());
}
}
Nota: Sé que puede evitar la traducción hacia y desde los objetos File en el ejemplo anterior mediante el uso de Files :: getLastModifiedTime api en la operación de flujo ordenado, sin embargo, debe lidiar con las excepciones de IO comprobadas dentro de su lambda, que siempre es un problema . Diría que si el rendimiento es lo suficientemente crítico como para que la traducción sea inaceptable, entonces trataría con la IOException marcada en el lambda propagándola como UncheckedIOException o renunciaría a la API de Archivos por completo y trataría solo con objetos File:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));