Chcę uzyskać listę plików w katalogu, ale chcę posortować ją tak, aby najstarsze pliki były pierwsze. Moim rozwiązaniem było wywołanie File.listFiles i po prostu skorzystanie z listy opartej na File.lastModified, ale zastanawiałem się, czy istnieje lepszy sposób.
Edycja: Moje obecne rozwiązanie, zgodnie z sugestią, polega na użyciu anonimowego Komparatora:
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()
wiele razy. Lepiej pobierz wszystkie daty najpierw, a zamów później, abyfile.lastModified()
wywoływać je tylko raz na plik.Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
Arrays.sort(files, Comparator.comparingLong(File::lastModified));
Odpowiedzi:
Myślę, że twoje rozwiązanie jest jedynym rozsądnym sposobem. Jedynym sposobem na uzyskanie listy plików jest użycie File.listFiles (), a dokumentacja stwierdza, że nie daje to żadnych gwarancji co do kolejności zwracanych plików. Dlatego musisz napisać Komparator, który używa File.lastModified () i przekazać go wraz z tablicą plików do Arrays.sort () .
źródło
Może to być szybsze, jeśli masz wiele plików. Wykorzystuje to wzorzec dekoruj-sortuj-i dekoruj, dzięki czemu data ostatniej modyfikacji każdego pliku jest pobierana tylko raz, a nie za każdym razem, gdy algorytm sortowania porównuje dwa pliki. To potencjalnie zmniejsza liczbę wywołań We / Wy z O (n log n) do O (n).
Jest to jednak więcej kodu, więc powinno się go używać tylko wtedy, gdy martwisz się głównie szybkością, i jest to znacznie szybsze w praktyce (czego nie sprawdziłem).
źródło
Eleganckie rozwiązanie od Java 8:
Lub, jeśli chcesz to w kolejności malejącej, po prostu odwróć:
źródło
files.sort(Comparator.comparingLong(File::lastModified));
ArrayList<File> files = new ArrayList<File>(Arrays.asList(directory.listFiles()))
, to nie jest łatwiejsze niż tylkoFile[] files = directory.listFiles()
.ArrayList<File>(...)
komentarz w komentarzu viniciussss jest potrzebny, aby uzyskać zmienną listę, którą można posortować.) Znalazłem ten wątek, szukając sposobu na posortowanie listy plików. Właśnie dodałem ten kod, aby ludzie mogli go po prostu skopiować, jeśli mają również listy.Comparator
Klasa nie ma żadnego wywołanie metodycomparingLong
Co z podobnym podejściem, ale bez boksu dla długich obiektów:
źródło
Możesz także spojrzeć na wspólne We / Wy Apache , ma on wbudowany ostatnio zmodyfikowany komparator i wiele innych przydatnych narzędzi do pracy z plikami.
źródło
W Javie 8:
Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));
źródło
Importuje:
Apache Commons
Kod :
źródło
Jeśli sortowane pliki można modyfikować lub aktualizować w tym samym czasie, sortowanie jest wykonywane:
Java 8+
Java 7
Oba te rozwiązania tworzą tymczasową strukturę danych mapy, aby zaoszczędzić stały czas ostatniej modyfikacji każdego pliku w katalogu. Powodem, dla którego musimy to zrobić, jest to, że jeśli twoje pliki są aktualizowane lub modyfikowane podczas sortowania, twój komparator naruszy wymagania dotyczące przechodniości umowy generalnej interfejsu komparatora, ponieważ czasy ostatniej modyfikacji mogą się zmieniać podczas porównania.
Jeśli z drugiej strony wiesz, że pliki nie zostaną zaktualizowane lub zmodyfikowane podczas sortowania, możesz uciec od prawie każdej innej odpowiedzi przesłanej na to pytanie, której częściowo jestem zdania:
Java 8+ (bez jednoczesnych modyfikacji podczas sortowania)
Uwaga: Wiem, że możesz uniknąć tłumaczenia na i z obiektów File w powyższym przykładzie, używając Files :: getLastModifiedTime api w posortowanym strumieniu, jednak musisz poradzić sobie ze sprawdzonymi wyjątkami IO wewnątrz lambda, co zawsze jest uciążliwe . Powiedziałbym, że jeśli wydajność jest na tyle krytyczna, że tłumaczenie jest niedopuszczalne, wówczas albo poradziłbym sobie ze sprawdzonym wyjątkiem IOException w lambda, propagując go jako UncheckedIOException, albo całkowicie zrezygnowałem z interfejsu API plików i zajmowałem się tylko obiektami File:
źródło
źródło
gdzie
listFiles
jest zbiorem wszystkich plików w ArrayListźródło
Możesz spróbować guava Zamawianie :
źródło
Możesz użyć biblioteki Apache LastModifiedFileComparator
źródło
źródło
Przyszedłem do tego postu, gdy szukałem tego samego problemu, ale w
android
. Nie twierdzę, że jest to najlepszy sposób na posortowanie plików według daty ostatniej modyfikacji, ale jest to najłatwiejszy sposób, jaki znalazłem.Poniższy kod może być komuś pomocny
Dzięki
źródło
for
pętli widać Brałemlist.length-1
zapisu doi >=0
którego po prostu iterate Państwo w odwrotnej kolejności.Istnieje bardzo łatwy i wygodny sposób rozwiązania problemu bez dodatkowego komparatora. Wystarczy zmodyfikować zmodyfikowaną datę w ciągu za pomocą nazwy pliku, posortować ją, a następnie ponownie usunąć.
Użyj ciągu o stałej długości 20, umieść w nim zmodyfikowaną datę (długą) i wypełnij wiodącymi zerami. Następnie po prostu dodaj nazwę pliku do tego ciągu:
Oto, co się dzieje:
Nazwa pliku1: C: \ data \ file1.html Ostatnia modyfikacja: 1532914451455 Ostatnia modyfikacja 20 cyfr: 00000001532914451455
Nazwa pliku1: C: \ data \ file2.html Ostatnia modyfikacja: 1532918086822 Ostatnia modyfikacja 20 cyfr: 00000001532918086822
przekształca nazwy plików na:
Nazwa pliku1: 00000001532914451455C: \ data \ plik1.html
Nazwa pliku2: 00000001532918086822C: \ data \ plik2.html
Następnie możesz po prostu posortować tę listę.
Wszystko, co musisz zrobić, to usunąć ponownie 20 znaków później (w Javie 8 możesz usunąć go dla całej tablicy za pomocą tylko jednego wiersza za pomocą funkcji .replaceAll)
źródło
Istnieje również zupełnie inny sposób, który może być jeszcze łatwiejszy, ponieważ nie mamy do czynienia z dużymi liczbami.
Zamiast sortować całą tablicę po pobraniu wszystkich nazw plików i dat ostatniej modyfikacji, możesz po prostu wstawić każdą pojedynczą nazwę pliku zaraz po pobraniu jej z właściwej pozycji na liście.
Możesz to zrobić w następujący sposób:
Po dodaniu obiektu 2 do pozycji 2 przesunie obiekt 3 do pozycji 3.
źródło