wie man File.listFiles in alphabetischer Reihenfolge?


95

Ich habe folgenden Code:

class ListPageXMLFiles implements FileFilter {

        @Override
        public boolean accept(File pathname) {
                DebugLog.i("ListPageXMLFiles", "pathname is " + pathname);

                String regex = ".*page_\\d{2}\\.xml";
                if(pathname.getAbsolutePath().matches(regex)) {
                        return true;
                }
                return false;
        }
}

public void loadPageTrees(String xml_dir_path) {
        ListPageXMLFiles filter_xml_files = new ListPageXMLFiles();
        File XMLDirectory = new File(xml_dir_path);
        for(File _xml_file : XMLDirectory.listFiles(filter_xml_files)) {
                loadPageTree(_xml_file);
        }
}

Das FileFilterfunktioniert gut, listFiles()scheint aber die Dateien in umgekehrter alphabetischer Reihenfolge aufzulisten. Gibt es eine schnelle Möglichkeit, listFile()die Dateien in alphabetischer Reihenfolge aufzulisten?


1
Verwenden Sie .endsWith(".xml")stattdessen Regex .
Fred

Antworten:


221

Die listFilesMethode mit oder ohne Filter garantiert keine Bestellung.

Es wird jedoch ein Array zurückgegeben, mit dem Sie sortieren können Arrays.sort().

File[] files = XMLDirectory.listFiles(filter_xml_files);
Arrays.sort(files);
for(File _xml_file : files) {
    ...
}

Dies funktioniert, weil Filees sich um eine vergleichbare Klasse handelt, die Pfadnamen standardmäßig lexikografisch sortiert. Wenn Sie sie anders sortieren möchten, können Sie Ihren eigenen Komparator definieren.

Wenn Sie Streams bevorzugen:

Ein moderner Ansatz ist der folgende. Gehen Sie folgendermaßen vor, um die Namen aller Dateien in einem bestimmten Verzeichnis in alphabetischer Reihenfolge zu drucken:

Files.list(Paths.get(dirName)).sorted().forEach(System.out::println)

Ersetzen Sie das System.out::printlndurch alles, was Sie mit den Dateinamen tun möchten. Wenn Sie nur Dateinamen möchten, die mit "xml"just do enden:

Files.list(Paths.get(dirName))
    .filter(s -> s.toString().endsWith(".xml"))
    .sorted()
    .forEach(System.out::println)

Ersetzen Sie den Druck erneut durch den gewünschten Verarbeitungsvorgang.


Dies ist eine schöne Codezeile, aber Arrays.sort () scheint void anstelle eines Iterable zurückzugeben. Ich werde ein bisschen herumstöbern.
Thunder Rabbit

3
@Thunder Rabbit, ich entschuldige mich !! Tut mir leid, du hast recht. Ich hätte es testen sollen. Ich habe meine Antwort bearbeitet.
Ray Toal

Es scheint in Windows gut zu funktionieren, aber in Ubuntu werden Ordner mit Großbuchstaben zuerst angezeigt als die anderen.
jmhostalet

5
So würde ich erwarten, dass es funktioniert. Großbuchstaben stehen in Unicode vor Kleinbuchstaben. Unixe haben Dateinamen, bei denen zwischen Groß- und Kleinschreibung unterschieden wird, sodass Großbuchstaben an erster Stelle stehen. Wenn Sie unter Windows Dateinamen verwenden, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird, werden Groß- und Kleinschreibung gemischt. Dies ist völlig wie erwartet. Wenn Sie Windows unter Unix verwenden möchten, geben Sie einen Komparator an sort.
Ray Toal

2

Ich denke, die vorherige Antwort ist der beste Weg, dies hier zu tun, ist ein anderer einfacher Weg. nur um die sortierten Ergebnisse zu drucken.

 String path="/tmp";
 String[] dirListing = null;
 File dir = new File(path);
 dirListing = dir.list();
 Arrays.sort(dirListing);
 System.out.println(Arrays.deepToString(dirListing));

Würden Sie bitte einen Kommentar abgeben, warum Sie denken, dass dies keine richtige Antwort ist? Also kann ich es entsprechend überarbeiten.
Grepit

1
-1 Ich verstehe den Vorteil, das Datei-Array in ein String-Array zu konvertieren und dann zu sortieren, anstatt nur das Datei-Array wie in der akzeptierten Antwort zu sortieren, wirklich nicht.
Zelanix

@zelanix danke für das Feedback. Ich habe nicht alle Antworten und mache manchmal Fehler bei der Beantwortung der Fragen. Ich habe die Antwort aktualisiert. Bitte überprüfen Sie sie und prüfen Sie, ob dies eine bessere Lösung ist. Ich würde mich freuen, wenn Sie Ihre Abstimmung überdenken könnten. Danke im Voraus.
Grepit

1
Ok, jetzt begründen Sie, warum es einfacher ist, wenn Sie nur die Ergebnisse drucken möchten, damit ich meine Ablehnung entfernen kann.
Zelanix

3
@ CPU100 Ich glaube, dass die Verwendung von list () anstelle von listFiles () den Vorteil bietet, nur die Dateinamen ohne die übergeordneten Verzeichnispfade zu haben, was zu kürzeren Zeichenfolgen und einer geringeren CPU-Zeit zum Sortieren / Vergleichen führt.
Diljeet

1

In Java 8:

Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));

Umgekehrte Reihenfolge:

Arrays.sort(files, (a, b) -> -a.getName().compareTo(b.getName()));

2
Sie können diesen Code auch verwenden:Arrays.sort(fList, Comparator.comparing(File::getName));
Plaidshirt

Sei vorsichtig damit. Dieser Code ist nicht deterministisch und sollte nicht unverändert verwendet werden.
Tony Schwartz

0

Das ist mein Code:

        try {
            String folderPath = "../" + filePath.trim() + "/";
            logger.info("Path: " + folderPath);
            File folder = new File(folderPath);
            File[] listOfFiles = folder.listFiles();
            int length = listOfFiles.length;
            logger.info("So luong files: " + length);
            ArrayList<CdrFileBO> lstFile = new ArrayList< CdrFileBO>();

            if (listOfFiles != null && length > 0) {
                int count = 0;
                for (int i = 0; i < length; i++) {
                    if (listOfFiles[i].isFile()) {
                        lstFile.add(new CdrFileBO(listOfFiles[i]));
                    }
                }
                Collections.sort(lstFile);
                for (CdrFileBO bo : lstFile) {
                    //String newName = START_NAME + "_" + getSeq(SEQ_START) + "_" + DateSTR + ".s";
                    String newName = START_NAME + DateSTR + getSeq(SEQ_START) + ".DAT";
                    SEQ_START = SEQ_START + 1;
                    bo.getFile().renameTo(new File(folderPath + newName));
                    logger.info("newName: " + newName);
                    logger.info("Next file: " + getSeq(SEQ_START));
                }

            }
        } catch (Exception ex) {
            logger.error(ex);
            ex.printStackTrace();
        }

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.