Лучший способ перечислить файлы в Java, отсортированных по дате изменения?



Я хочу получить список файлов в Каталоге, но я хочу, чтобы отсортировать его так, что старые файлы первыми. Мое решение было вызвать файл.listFiles и просто прибегают к списку на основе файла.lastModified, но мне было интересно, есть ли лучший способ.



Edit: мое текущее решение, как и предлагалось, заключается в использовании анонимного компаратора:



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());
} });
1785   16  

16 ответов:

Я думаю, что ваше решение является единственным разумным способом. Единственный способ получить список файлов-использовать .файл-список() и в документации говорится, что это не дает никаких гарантий о порядке файлов возвращается. Поэтому вам нужно написать компаратор использует .lastModified() и передайте это вместе с массивом файлов в массивы.сортировка ().

Это может быть быстрее, если у вас много файлов. При этом используется шаблон 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;

Как насчет аналогичного подхода, но без бокса к длинным объектам:

File[] files = directory.listFiles();

Arrays.sort(files, new Comparator<File>() {
    public int compare(File f1, File f2) {
        return Long.compare(f1.lastModified(), f2.lastModified());
    }
});

вы также можете посмотреть на Apache commons IO, Он построен в последняя модификация компаратора и многие другие приятные утилиты для работы с файлами.

элегантное решение с использованием 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());

В Java 8:

Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));

импорт :

org.apache.commons.io.comparator.LastModifiedFileComparator

Apache Commons

код :

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

    }

если файлы, которые вы сортируете, изменяются / обновляются во время выполнения сортировки, вы нарушаете требование транзитивности генерального контракта компаратора. Чтобы избежать этой потенциальной ошибки, вы хотите создать статическую таблицу поиска последних измененных значений для использования в компараторе для каждого файла, что-то вроде следующего:

    Collection<File> files = ...
    final Map<File, Long> staticLastModifiedTimes = new HashMap<File,Long>();
    for(final File f : files) {
        staticLastModifiedTimes.put(f, f.lastModified());
    }
    Collections.sort(files, new Comparator<File>() {
        @Override
        public int compare(final File f1, final File f2) {
            return staticLastModifiedTimes.get(f1).compareTo(staticLastModifiedTimes.get(f2));
        }
    });
public String[] getDirectoryList(String path) {
    String[] dirListing = null;
    File dir = new File(path);
    dirListing = dir.list();

    Arrays.sort(dirListing, 0, dirListing.length);
    return dirListing;
}

вы можете попробовать гуаву заказ:

Function<File, Long> getLastModified = new Function<File, Long>() {
    public Long apply(File file) {
        return file.lastModified();
    }
};

List<File> orderedFiles = Ordering.natural().onResultOf(getLastModified).
                          sortedCopy(files);

вы можете использовать Apache LastModifiedFileComparator библиотека

 import org.apache.commons.io.comparator.LastModifiedFileComparator;  


File[] files = directory.listFiles();
        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
        for (File file : files) {
            Date lastMod = new Date(file.lastModified());
            System.out.println("File: " + file.getName() + ", Date: " + lastMod + "");
        }
private static List<File> sortByLastModified(String dirPath) {
    List<File> files = listFilesRec(dirPath);
    Collections.sort(files, new Comparator<File>() {
        public int compare(File o1, File o2) {
            return Long.compare(o1.lastModified(), o2.lastModified());
        }
    });
    return files;
}

Я пришел к этому сообщению, когда я искал ту же проблему, но в android. Я не говорю, что это лучший способ отсортировать файлы по дате последнего изменения, но это самый простой способ, который я нашел еще.

ниже код может быть полезен кому-то -

File downloadDir = new File("mypath");    
File[] list = downloadDir.listFiles();
    for (int i = list.length-1; i >=0 ; i--) {
        //use list.getName to get the name of the file
    }

спасибо

Collections.sort(listFiles, new Comparator<File>() {
        public int compare(File f1, File f2) {
            return Long.compare(f1.lastModified(), f2.lastModified());
        }
    });

здесь listFiles это коллекция всех файлов в ArrayList

есть также совершенно другой способ, который может быть еще проще, так как мы не имеем дело с большими числами.

вместо сортировки всего массива после того, как вы получили все имена файлов и даты lastModified, вы можете просто вставить каждое имя файла сразу после того, как вы получили его в нужной позиции списка.

вы можете сделать это так:

list.add(1, object1)
list.add(2, object3)
list.add(2, object2)

после добавления объекта 2 в позицию 2 он переместит объект 3 в позицию 3.

есть очень простой и удобный способ справиться с проблемой без какого-либо дополнительного компаратора. Просто Закодируйте измененную дату в строку с именем файла, отсортируйте ее, а затем снова удалите ее.

используйте строку фиксированной длины 20, поместите в нее измененную дату (длинную) и заполните ее ведущими нулями. Затем просто добавьте имя файла в эту строку:

String modified_20_digits = ("00000000000000000000".concat(Long.toString(temp.lastModified()))).substring(Long.toString(temp.lastModified()).length()); 

result_filenames.add(modified_20_digits+temp.getAbsoluteFile().toString());

что происходит здесь:

Filename1: C:\data\file1.HTML-код последнего изменения:1532914451455 Последнее Изменение 20 Цифр: 00000001532914451455

Filename1: C:\data\file2.html Последнее изменение: 1532918086822 Последнее изменение 20 цифр: 00000001532918086822

преобразует имена файлов в:

Filename1: 00000001532914451455C:\data\file1.HTML-код

Filename2: 00000001532918086822C:\data\file2.HTML-код

вы можете просто отсортировать этот список.

все, что вам нужно сделать, это лишить 20 символов снова позже (в Java 8, вы можете лишить его для всего массива с помощью только одной строки .функция заменяет)

Comments

    Ничего не найдено.