how to File.listFiles in alphabetical order?
Asked Answered
M

4

111

I've got code as below:

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

The FileFilter is working nicely, but listFiles() seems to be listing the files in reverse alphabetical order. Is there some quick way of telling listFile() to list the files in alphabetical order?

Mussel answered 26/8, 2011 at 4:4 Comment(1)
Instead of using regex, use .endsWith(".xml") instead.Jin
T
253

The listFiles method, with or without a filter does not guarantee any order.

It does, however, return an array, which you can sort with Arrays.sort().

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

This works because File is a comparable class, which by default sorts pathnames lexicographically. If you want to sort them differently, you can define your own comparator.

If you prefer using Streams:

A more modern approach is the following. To print the names of all files in a given directory, in alphabetical order, do:

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

Replace the System.out::println with whatever you want to do with the file names. If you want only filenames that end with "xml" just do:

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

Again, replace the printing with whichever processing operation you would like.

Trilly answered 26/8, 2011 at 4:8 Comment(4)
This is one beautiful line of code, but Arrays.sort() seems to return void, instead of an Iterable. I'll poke around a bit.Mussel
@Thunder Rabbit, My Apologies!! So sorry, you are right. I should have tested it. I edited my answer.Trilly
It seems to be working fine in Windows, but in Ubuntu folders with capital letters appear first than the rest.Gobi
That's the way I would expect it to work. Capital letters come before lower case letters in Unicode. Unixes have case-sensitive filenames, so capital letters come first. If you are using case-insensitive filenames on Windows, the capitals and lowercase names will be mixed together. This is completely as expected. If you want the Windows way on a Unix, supply a comparator to sort.Trilly
C
4

In Java 8:

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

Reverse order:

Arrays.sort(files, (a, b) -> -a.getName().compareTo(b.getName()));
Carrycarryall answered 14/3, 2019 at 13:30 Comment(3)
You can use this code too: Arrays.sort(fList, Comparator.comparing(File::getName));Melodeemelodeon
Be careful with this. This code is non-deterministic and should not be used as is.War
Why not, and whose code?Snowdrift
E
2

I think the previous answer is the best way to do it here is another simple way. just to print the sorted results.

 String path="/tmp";
 String[] dirListing = null;
 File dir = new File(path);
 dirListing = dir.list();
 Arrays.sort(dirListing);
 System.out.println(Arrays.deepToString(dirListing));
Enchiridion answered 7/9, 2012 at 18:57 Comment(5)
would you please provide comment as why you think this is not a correct answer. So, I can revise it accordingly.Enchiridion
-1 I really don't understand the advantage of converting the file array to a string array and then sorting rather than just sorting the file array as the accepted answer does.Nonobservance
@Nonobservance thanks for providing the feedback. I don't have all the answers and I make mistakes sometimes answering the questions. I have updated the answer, would you please review it and see if this is a better solution.I would appreciate it if you could reconsider your vote. Thanks in advance.Enchiridion
Ok, now you justify why it's simpler if you just want to print the results so I will remove my downvote.Nonobservance
@CPU100 i believe that by using the list() instead of listFiles() gives the advantage of having only the file names without the parent directory paths, resulting in shorter strings and lesser cpu time to sort/compare.Mccarthyism
S
0

This is my 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();
        }
Siderite answered 26/10, 2018 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.