Получить файлы в каталоге, отсортированном по последнему измененному?

В Java 7 с новыми API-интерфейсами ввода-вывода есть ли простой способ перечислить содержимое каталога по дате последнего изменения? В основном мне нужно только получить файл, который не был изменен в течение самого долгого времени (сортировка по последнему измененному возрастанию, первое имя файла).

Ответ 1

Там нет реального "простого способа", но это возможно:

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
        }
    }
});

Это приведет к сортировке файлов, скопированных последним. DirectoryStream не перебирать подкаталоги.

Ответ 2

Небольшое "потоковое" изменение ответа Джеффри, которое, возможно, также станет легче. Публикация для полноты.

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 -> {
        });
}

Ответ 3

Используйте listFiles() в каталоге File object. Преобразуйте массив в arraylist. Затем отсортируйте их с помощью метода статической сортировки в классе Collections с помощью специального Comparator, который использует метод getTotalSpace() в файлах. EDIT: используйте lastModified вместо getTotalSpace.

Ответ 4

lastModified()

Возвращает время последнего изменения файла, обозначенного этим абстрактным именем пути.

Java 7 - IO API

Ответ 5

вы можете использовать http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter) и поставлять http://docs.oracle.com/javase/1.5.0/docs/api/java/io/FileFilter.html

затем сравните http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified(), и вы закончили

если вы заботитесь о производительности, а затем просто возьмите с максимальным/минимальным значением из списка файлов, что даст вам сложность O (n)

Ответ 6

Примечание. Для этого решения требуется Guava.

API Java IO/NIO обеспечивает низкоуровневый доступ к спискам каталогов, но обработка не выполняется, что остается для вызывающего. Новый Java7 NIO DirectoryStream имеет минимальный след при доступе к списку каталогов для дальнейшей обработки, например. сортировка.

Вот мое решение: прочитайте файлы из DirectoryStream и создайте отсортированную очередь с (необязательно) ограниченным размером из потока. Верните самые старые/новейшие элементы из очереди.

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

}

Эти зависимости требуются для Guava MinMaxPriorityQueue и 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>

Вы также можете найти параметр фильтр параметра Files.newDirectoryStream:

    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)