- Лучший способ перечислить файлы на Java, отсортированные по дате изменения?
- 17 ответы
- Если файлы, которые вы сортируете, могут быть изменены или обновлены одновременно с сортировкой:
- Java 8 +
- Java 7
- Java 8+ (без одновременных модификаций во время сортировки)
- How to sort Text file content in Java
- Steps to Sort the txt file content:
- Read contents of the text file:
- Store the contents in an ArrayList:
- Sort the arrayList:
- Write the contents to another text file:
- Full Program to sort contents of text file:
- Сортировка списка файлов по алфавиту
Лучший способ перечислить файлы на Java, отсортированные по дате изменения?
Я хочу получить список файлов в каталоге, но я хочу отсортировать его так, чтобы самые старые файлы были первыми. Мое решение состояло в том, чтобы вызвать File.listFiles и просто использовать список на основе File.lastModified, но мне было интересно, есть ли лучший способ.
Изменить: мое текущее решение, как было предложено, — использовать анонимный компаратор:
File[] files = directory.listFiles(); Arrays.sort(files, new Comparator() < public int compare(File f1, File f2) < return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified()); >>);
что с «новой длинной» частью этого? почему бы вам просто не сравнить сами длинные позиции? это позволило бы избежать создания тонны длинных запросов только для того, чтобы добраться до метода compareTo . — John Gardner
Этот код не компилируется. Методы сравнения ожидают, что возвращаемое значение будет int, а не Long. — marcospereira
Я единственный, кто считает это решение безумным? Ты звонишь file.lastModified() огромное количество раз. Лучше сначала получить все даты и заказать позже, чтобы file.lastModified() вызывается только один раз для каждого файла. — cprcrack
Вы можете использовать компаратор apache commons: Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE); — jlunavtgrad
Есть лучшее решение с Java 8 (см. Ответ viniciussss): Arrays.sort(files, Comparator.comparingLong(File::lastModified)); — starbroken
17 ответы
Я думаю, что ваше решение — единственно разумный путь. Единственный способ получить список файлов — использовать File.listFiles () и в документации указано, что это не дает никаких гарантий относительно порядка возвращаемых файлов. Поэтому вам нужно написать Компаратор который использует File.lastModified () и передайте это вместе с массивом файлов в Arrays.sort ().
Как тут поправить форматирование? В превью смотрится нормально но 4я ссылка прикручена. — Дэн Дайер
File.lastModified может измениться во время сортировки конечного результата из-за ошибки нарушения метода сравнения, см.: stackoverflow.com/questions/20431031. Читать stackoverflow.com/a/4248059/314089 для возможного лучшего решения. — ледяной резак
Элегантное решение начиная с Java 8:
File[] files = directory.listFiles(); Arrays.sort(files, Comparator.comparingLong(File::lastModified));
Или, если вы хотите его в порядке убывания, просто измените его:
File[] files = directory.listFiles(); Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
Это действительно самое простое решение. Для списков: files.sort(Comparator.comparingLong(File::lastModified)); — разбитый звездами
@starbroken Ваше решение не работает, если файлы представляют собой простой массив, например File [], который возвращается функцией directory.listFiles (). — винисиуссс
@starbroken Чтобы ваше решение работало, нужно использовать ArrayList files = new ArrayList(Arrays.asList(directory.listFiles())) , это не проще, чем просто File[] files = directory.listFiles() . — винисиуссс
Да, я согласен с тобой. Если у вас есть массив файлов, нет смысла создавать список. (Если кому-то интересно, этот «дополнительный» ArrayList(. ) в viniciussss комментарий необходим для получения изменяемого списка, который можно отсортировать.) Я нашел эту ветку в поисках способа отсортировать список файлов. Поэтому я просто добавил этот код, чтобы люди могли просто скопировать его, если у них тоже есть списки. — разбитый звездами
Наблюдения и советы этой статьи мы подготовили на основании опыта команды Comparator класс не имеет вызова метода comparingLong — Зелевен
Это может быть быстрее, если у вас много файлов. Здесь используется шаблон decorate-sort-undecorate, так что выбирается только дата последнего изменения каждого файла. консолидировать а не каждый раз, когда алгоритм сортировки сравнивает два файла. Это потенциально снижает количество вызовов ввода-вывода с O (n log n) до O (n).
Однако это больше кода, поэтому его следует использовать только в том случае, если вы в основном озабочены скоростью, и на практике это заметно быстрее (что я не проверял).
class Pair implements Comparable < public long t; public File f; public Pair(File file) < f = file; t = file.lastModified(); >public int compareTo(Object o) < long u = ((Pair) o).t; return t < u ? -1 : t == u ? 0 : 1; >>; // Obtain the array of (file, timestamp) pairs. File[] files = directory.listFiles(); Pair[] pairs = new Pair[files.length]; for (int i = 0; i < files.length; i++) pairs[i] = new Pair(files[i]); // Sort them by timestamp. Arrays.sort(pairs); // Take the sorted pairs and extract only the file part, discarding the timestamp. for (int i = 0; i < files.length; i++) files[i] = pairs[i].f;
Лучший ответ, поскольку он, вероятно, единственный, предотвращающий «ошибку нарушения метода сравнения», если lastModified изменяется во время сортировки? - ледяной резак
Это также следует использовать, когда вы беспокоитесь о том, чтобы не получить исключение IllegalArgumentException из-за нарушения метода сравнения. Метод, использующий карту, завершится ошибкой, если существует более одного файла с одинаковым значением lastModified, что приведет к пропуску этих файлов. Это определенно должен быть принятый ответ. - Разработчик Android
Насчет аналогичного подхода, но без бокса к объектам Long:
File[] files = directory.listFiles(); Arrays.sort(files, new Comparator() < public int compare(File f1, File f2) < return Long.compare(f1.lastModified(), f2.lastModified()); >>);
Кажется, это только API 19+. - Габор
Используйте return Long.valueOf (f1.lastModified ()). CompareTo (f2.lastModified ()); вместо этого для более низких API. - Мартин Сайкс
Вы также можете посмотреть Apache Commons IO, он имеет встроенный последний измененный компаратор и множество других приятных утилит для работы с файлами.
В javadoc есть странная ошибка с этим решением, потому что javadoc говорит использовать «LastModifiedFileComparator.LASTMODIFIED_COMPARATOR.sort (list);» для сортировки списка, но LASTMODIFIED_COMPARATOR объявлен как "Компаратор ", поэтому он не предоставляет никаких методов" сортировки ". - Тристан
File.lastModified может измениться во время сортировки конечного результата из-за ошибки нарушения метода сравнения, см.: stackoverflow.com/questions/20431031. Читать stackoverflow.com/a/4248059/314089 для возможного лучшего решения. - ледяной резак
люблю Apache Commons, что сэкономило много времени, - Красный дьявол
Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));
org.apache.commons.io.comparator.LastModifiedFileComparator
public static void main(String[] args) throws IOException < File directory = new File("."); // get just files, not directories File[] files = directory.listFiles((FileFilter) FileFileFilter.FILE); System.out.println("Default order"); displayFiles(files); Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); System.out.println("\nLast Modified Ascending Order (LASTMODIFIED_COMPARATOR)"); displayFiles(files); Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE); System.out.println("\nLast Modified Descending Order (LASTMODIFIED_REVERSE)"); displayFiles(files); >
ответ дан 29 мар '16, в 21:03
Не сразу понятно, откуда берется LastModifiedFileComparator.LASTMODIFIED_COMPARATOR. Возможно добавление ссылки на Apache Commons io помог бы. - широкополосный
Если файлы, которые вы сортируете, могут быть изменены или обновлены одновременно с сортировкой:
Java 8 +
private static List listFilesOldestFirst(final String directoryPath) throws IOException < try (final StreamfileStream = 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 Listinstead of List .collect(Collectors.toList()); > >
Java 7
private static List listFilesOldestFirst(final String directoryPath) throws IOException < final Listfiles = Arrays.asList(new File(directoryPath).listFiles()); final Map constantLastModifiedTimes = new HashMap(); for (final File f : files) < constantLastModifiedTimes.put(f, f.lastModified()); >Collections.sort(files, new Comparator() < @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 listFilesOldestFirst(final String directoryPath) throws IOException < try (final StreamfileStream = 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 Listinstead of List .collect(Collectors.toList()); > >
Примечание. Я знаю, что вы можете избежать перевода в объекты File и обратно в приведенном выше примере, используя Files :: getLastModifiedTime api в операции с отсортированным потоком, тогда вам нужно иметь дело с проверенными исключениями ввода-вывода внутри вашей лямбда, что всегда является проблемой. Я бы сказал, что если производительность настолько критична, что перевод неприемлем, тогда я бы либо имел дело с проверенным IOException в лямбде, распространяя его как UncheckedIOException, либо я бы вообще отказался от API файлов и работал только с объектами File:
final List sorted = Arrays.asList(new File(directoryPathString).listFiles()); sorted.sort(Comparator.comparing(File::lastModified));
ответ дан 03 мар '20, в 21:03
How to sort Text file content in Java
Write a java program or method to sort a text file containing some records. The program should take a text file containing some records as input parameter, then sort the records either alphabetically and write the sorted content in another text file.
Steps to Sort the txt file content:
- Read contents of the text file.
- Store the contents in an ArrayList.
- Sort the ArrayList with Collection.sort() method.
- Write this sorted content to another text file.
Read contents of the text file:
We create a BufferedReader object and pass our file to it in the form of FileReader object.
Store the contents in an ArrayList:
We don't know the length of content in the text file, so we need a dynamic size data structure and ArrayList fulfills this purpose.
We read the file line by line and store add it in our ArrayList.
Sort the arrayList:
Java Collections provide an easy way to sort the data of any Collection by using sort() method. By default sort() method is used to sort the elements present in the list in ascending order. sort() method is found in java.util.Collections.
Write the contents to another text file:
Full Program to sort contents of text file:
import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; public class Example< public static void main(String[] args) throws IOException< BufferedReader reader = new BufferedReader(new FileReader("filePath")); ArrayList str = new ArrayList<>(); String line = ""; while((line=reader.readLine())!=null) < str.add(line); >reader.close(); Collections.sort(str); FileWriter writer = new FileWriter("new file"); for(String s: str) < writer.write(s); writer.write("\r\n"); >writer.close(); > >
Сортировка списка файлов по алфавиту
Я сиииильно начинающий, вот что-то сам по себе изучаю, книги читаю. Решил посмотреть, как с файлами работать, в качестве задания написал вот это:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
import java.io.IOException; import java.io.File; class Main { public static void checkin(File x) { File [] fld = x.listFiles(); for (int i = 0; i fld.length; i++) { if (fld[i].isFile()) { System.out.println(fld[i].getName()+" "+fld[i].length()+"B"); } else { checkin(fld[i]); } } } public static void main(String [] args) throws IOException { String path = args[0]; File folder = new File(path); checkin(folder); } }
И вот вопрос такой: а как сделать вывод сортированным по названию файла? Мой мозг сломан, не могу представить. Единственное, есть мысль запихнуть в ArrayList названия файлов и отсортировать дефолтным методом, но вообще слабо это себе представляю. В лист заливать только имена, или всю строку с размером? Откуда его запихивать?
Заранее извиняюсь, заранее всем спасибо=)
З.Ы. Для новичков тему не нашел - написал в корень. Не бейте.