comment File.listFiles par ordre alphabétique?

95

J'ai le code comme ci-dessous:

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

Le FileFilterfonctionne bien, mais listFiles()semble répertorier les fichiers dans l'ordre alphabétique inverse. Existe-t-il un moyen rapide de listFile()lister les fichiers par ordre alphabétique?

Lapin tonnerre
la source
1
Au lieu d'utiliser regex, utilisez à la .endsWith(".xml")place.
Fred

Réponses:

221

La listFilesméthode, avec ou sans filtre, ne garantit aucun ordre.

Il renvoie cependant un tableau avec lequel vous pouvez trier Arrays.sort().

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

Cela fonctionne parce que Filec'est une classe comparable, qui par défaut trie les chemins lexicographiquement. Si vous souhaitez les trier différemment, vous pouvez définir votre propre comparateur.

Si vous préférez utiliser Streams:

Une approche plus moderne est la suivante. Pour imprimer les noms de tous les fichiers d'un répertoire donné, par ordre alphabétique, procédez comme suit:

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

Remplacez le System.out::printlnpar ce que vous voulez faire avec les noms de fichiers. Si vous ne voulez que des noms de fichiers qui se terminent par, "xml"faites simplement:

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

Encore une fois, remplacez l'impression par l'opération de traitement que vous souhaitez.

Ray Toal
la source
C'est une belle ligne de code, mais Arrays.sort () semble retourner void, au lieu d'un Iterable. Je vais fouiller un peu.
Thunder Rabbit
3
@ Thunder Rabbit, mes excuses !! Désolé, vous avez raison. J'aurais dû le tester. J'ai édité ma réponse.
Ray Toal
Cela semble fonctionner correctement sous Windows, mais dans les dossiers Ubuntu avec des lettres majuscules apparaissent en premier que les autres.
jmhostalet
5
C'est ainsi que je m'attendrais à ce que cela fonctionne. Les majuscules précèdent les minuscules en Unicode. Les Unix ont des noms de fichiers sensibles à la casse, donc les majuscules viennent en premier. Si vous utilisez des noms de fichiers insensibles à la casse sous Windows, les noms en majuscules et en minuscules seront mélangés. C'est tout à fait comme prévu. Si vous voulez la manière Windows sur un Unix, fournissez un comparateur à sort.
Ray Toal
2

Je pense que la réponse précédente est la meilleure façon de le faire ici est une autre façon simple. juste pour imprimer les résultats triés.

 String path="/tmp";
 String[] dirListing = null;
 File dir = new File(path);
 dirListing = dir.list();
 Arrays.sort(dirListing);
 System.out.println(Arrays.deepToString(dirListing));
grepit
la source
pourriez-vous s'il vous plaît expliquer pourquoi vous pensez que cette réponse n'est pas correcte. Donc, je peux le réviser en conséquence.
grepit
1
-1 Je ne comprends vraiment pas l'avantage de convertir le tableau de fichiers en un tableau de chaînes, puis de trier plutôt que de simplement trier le tableau de fichiers comme le fait la réponse acceptée.
zelanix
@zelanix merci pour vos commentaires. Je n'ai pas toutes les réponses et je fais parfois des erreurs en répondant aux questions. J'ai mis à jour la réponse, pourriez-vous la lire et voir si c'est une meilleure solution. Je vous serais reconnaissant si vous pouviez reconsidérer votre vote. Merci d'avance.
grepit
1
Ok, maintenant vous justifiez pourquoi c'est plus simple si vous voulez juste imprimer les résultats afin que je supprime mon vote défavorable.
zelanix
3
@ CPU100 Je crois qu'en utilisant la liste () au lieu de listFiles () donne l'avantage de n'avoir que les noms de fichier sans les chemins du répertoire parent, ce qui entraîne des chaînes plus courtes et moins de temps CPU pour trier / comparer.
Diljeet
1

Dans Java 8:

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

Ordre inverse:

Arrays.sort(files, (a, b) -> -a.getName().compareTo(b.getName()));
Sergueï Rodionov
la source
2
Vous pouvez également utiliser ce code:Arrays.sort(fList, Comparator.comparing(File::getName));
plaidshirt
Soyez prudent avec cela. Ce code n'est pas déterministe et ne doit pas être utilisé tel quel.
Tony Schwartz le
0

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

Tru Nguyen
la source