Я хочу получить список файлов в каталоге, но хочу отсортировать его так, чтобы самые старые файлы были первыми. Мое решение состояло в том, чтобы вызвать File.listFiles и просто прибегнуть к списку, основанному на File.lastModified, но мне было интересно, есть ли лучший способ.
Изменить: мое текущее решение, как предлагается, заключается в использовании анонимного компаратора:
File[] files = directory.listFiles();
Arrays.sort(files, new Comparator<File>(){
public int compare(File f1, File f2)
{
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
} });
file.lastModified()
огромное количество раз. Лучше сначала получить все даты, а потом заказывать, чтобы ониfile.lastModified()
вызывались только один раз для каждого файла.Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
Arrays.sort(files, Comparator.comparingLong(File::lastModified));
Ответы:
Я думаю, что ваше решение - единственный разумный путь. Единственный способ получить список файлов - это использовать File.listFiles (), и в документации говорится, что это не дает никаких гарантий относительно порядка возвращаемых файлов. Поэтому вам нужно написать Comparator, который использует File.lastModified () и передать его вместе с массивом файлов в Arrays.sort () .
источник
Это может быть быстрее, если у вас много файлов. При этом используется шаблон decorate-sort-undecorate, чтобы дата последнего изменения каждого файла выбиралась только один раз, а не каждый раз, когда алгоритм сортировки сравнивает два файла. Это потенциально уменьшает количество вызовов ввода / вывода с O (n log n) до O (n).
Тем не менее, это больше кода, поэтому его следует использовать только в том случае, если вы в основном заинтересованы в скорости, и на практике это заметно быстрее (что я не проверял).
источник
Элегантное решение начиная с Java 8:
Или, если вы хотите в порядке убывания, просто измените его:
источник
files.sort(Comparator.comparingLong(File::lastModified));
ArrayList<File> files = new ArrayList<File>(Arrays.asList(directory.listFiles()))
, что не проще, чем простоFile[] files = directory.listFiles()
.ArrayList<File>(...)
в комментарии viniciussss необходимо для получения изменяемого списка, который можно отсортировать.) Я нашел эту ветку в поисках способа сортировки списка файлов. Поэтому я просто добавил этот код, чтобы люди могли просто скопировать его, если у них тоже есть списки.Comparator
Класс не имеет какой - либо вызов методаcomparingLong
Что касается аналогичного подхода, но без привязки к объектам Long:
источник
Вы также можете посмотреть на Apache commons IO , в него встроен последний измененный компаратор и множество других полезных утилит для работы с файлами.
источник
В Java 8:
Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));
источник
Импорт:
Apache Commons
Код:
источник
Если сортируемые файлы могут быть изменены или обновлены одновременно, сортировка выполняется:
Java 8+
Java 7
Оба эти решения создают временную структуру данных карты для сохранения постоянного времени последнего изменения для каждого файла в каталоге. Причина, по которой мы должны это сделать, заключается в том, что если ваши файлы обновляются или модифицируются во время выполнения сортировки, тогда ваш компаратор будет нарушать требование транзитивности общего контракта интерфейса компаратора, поскольку время последнего изменения может изменяться во время сравнения.
Если, с другой стороны, вы знаете, что файлы не будут обновляться или изменяться во время сортировки, вы можете получить практически любой другой ответ, представленный на этот вопрос, к которому я неравнодушен:
Java 8+ (нет одновременных изменений во время сортировки)
Примечание: я знаю, что вы можете избежать преобразования в и из объектов File в приведенном выше примере, используя api Files :: getLastModifiedTime в операции отсортированного потока, однако тогда вам придется иметь дело с проверенными исключениями ввода-вывода внутри лямбды, что всегда является проблемой , Я бы сказал, что если производительность достаточно критична, чтобы перевод был неприемлемым, то я бы либо имел дело с проверенным IOException в лямбда-выражении, передав его как UncheckedIOException, либо я бы вообще отказался от файлов api и имел дело только с объектами File:
источник
источник
где
listFiles
находится коллекция всех файлов в ArrayListисточник
Вы можете попробовать гуавы Заказ :
источник
Вы можете использовать библиотеку Apache LastModifiedFileComparator
источник
источник
Я пришел к этому сообщению, когда искал ту же проблему, но в
android
. Я не говорю, что это лучший способ получить отсортированные файлы по дате последнего изменения, но это самый простой способ, который я нашел.Ниже код может быть полезен для кого-то
Спасибо
источник
for
цикла вы можете видеть, что яlist.length-1
поднялся,i >=0
что просто повторяет вас в обратном порядке.Существует очень простой и удобный способ решения проблемы без дополнительного компаратора. Просто закодируйте измененную дату в строку с именем файла, отсортируйте ее, а затем снова удалите.
Используйте строку фиксированной длины 20, поместите в нее измененную дату (длинную) и заполните начальными нулями. Затем просто добавьте имя файла к этой строке:
Что здесь происходит, это:
Имя файла1: C: \ data \ file1.html Последнее изменение: 1532914451455 Последнее изменение 20 цифр: 00000001532914451455
Имя файла1: C: \ data \ file2.html Последнее изменение: 1532918086822 Последнее изменение 20 цифр: 00000001532918086822
преобразует имена файлов в:
Имя файла1: 00000001532914451455C: \ data \ file1.html
Имя файла2: 00000001532918086822C: \ data \ file2.html
Затем вы можете просто отсортировать этот список.
Все, что вам нужно сделать, это снова обрезать 20 символов позже (в Java 8 вы можете обрезать его для всего массива всего одной строкой, используя функцию .replaceAll)
источник
Существует также совершенно другой способ, который может быть даже проще, поскольку мы не имеем дело с большими числами.
Вместо того, чтобы сортировать весь массив после того, как вы извлекли все имена файлов и даты lastModified, вы можете просто вставить каждое отдельное имя файла сразу после того, как вы извлекли его в правильной позиции списка.
Вы можете сделать это так:
После того, как вы добавите объект 2 в положение 2, он переместит объект 3 в положение 3.
источник