come File.listFiles in ordine alfabetico?


95

Ho il codice come di seguito:

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

La FileFiltersta lavorando bene, ma listFiles()sembra essere l'elenco dei file in ordine alfabetico inverso. C'è un modo rapido per dire listFile()di elencare i file in ordine alfabetico?


1
Invece di usare regex, usa .endsWith(".xml")invece.
— Fred

Risposte:


221

Il listFiles metodo, con o senza filtro, non garantisce alcun ordine.

Tuttavia, restituisce un array, con il quale è possibile ordinare Arrays.sort().

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

Funziona perché Fileè una classe comparabile, che per impostazione predefinita ordina i nomi di percorso in modo lessicografico. Se vuoi ordinarli in modo diverso, puoi definire il tuo comparatore.

Se preferisci usare Streams:

Un approccio più moderno è il seguente. Per stampare i nomi di tutti i file in una determinata directory, in ordine alfabetico, eseguire:

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

Sostituisci System.out::printlncon quello che vuoi fare con i nomi dei file. Se vuoi solo nomi di file che finiscono con "xml"fai:

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

Di nuovo, sostituisci la stampa con qualsiasi operazione di elaborazione desideri.


Questa è una bellissima riga di codice, ma Arrays.sort () sembra restituire void, invece di un Iterable. Guardo un po 'in giro.
— Thunder Rabbit

3
@Thunder Rabbit, My Apologies !! Mi dispiace tanto, hai ragione. Avrei dovuto provarlo. Ho modificato la mia risposta.
— Ray Toal

Sembra funzionare bene in Windows, ma in Ubuntu le cartelle con le lettere maiuscole appaiono prima del resto.
— jmhostalet

5
È così che mi aspetto che funzioni. Le lettere maiuscole vengono prima delle lettere minuscole in Unicode. Gli Unix hanno nomi di file che fanno distinzione tra maiuscole e minuscole, quindi le lettere maiuscole vengono prima. Se utilizzi nomi di file senza distinzione tra maiuscole e minuscole su Windows, i nomi maiuscoli e minuscoli verranno mescolati insieme. Questo è completamente come previsto. Se vuoi il modo Windows su un Unix, fornisci un comparatore a sort.
— Ray Toal,

2

Penso che la risposta precedente sia il modo migliore per farlo qui è un altro modo semplice. solo per stampare i risultati ordinati.

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

forniresti un commento per spiegare perché pensi che questa non sia una risposta corretta. Quindi, posso rivederlo di conseguenza.
— grepit

1
-1 Non capisco davvero il vantaggio di convertire l'array di file in un array di stringhe e quindi ordinare piuttosto che ordinare semplicemente l'array di file come fa la risposta accettata.
— zelanix

@zelanix grazie per aver fornito il feedback. Non ho tutte le risposte ea volte faccio degli errori rispondendo alle domande. Ho aggiornato la risposta, la prego di esaminarla e vedere se questa è una soluzione migliore. Apprezzerei se potesse riconsiderare il suo voto. Grazie in anticipo.
— grepit

1
Ok, ora giustifica perché è più semplice se vuoi solo stampare i risultati, quindi rimuoverò il mio voto negativo.
— zelanix

3
@ CPU100 credo che l'uso di list () invece di listFiles () offra il vantaggio di avere solo i nomi dei file senza i percorsi della directory principale, risultando in stringhe più brevi e meno tempo della CPU per ordinare / confrontare.
— Diljeet

1

In Java 8:

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

Ordine inverso:

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

2
Puoi usare anche questo codice:Arrays.sort(fList, Comparator.comparing(File::getName));
— plaidshirt

Stai attento con questo. Questo codice non è deterministico e non deve essere utilizzato così com'è.
— Tony Schwartz,

0

Questo è il mio codice:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.