bagaimana cara File.listFiles dalam urutan abjad?

95

Saya punya kode seperti di bawah ini:

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

Ini FileFilterberfungsi dengan baik, tetapi listFiles()tampaknya mencantumkan file dalam urutan abjad terbalik. Adakah cara cepat untuk memberi tahu listFile()daftar file dalam urutan abjad?

Kelinci Guntur
sumber
1
Alih-alih menggunakan regex, gunakan .endsWith(".xml")saja.
Fred

Jawaban:

221

The listFilesmetode, dengan atau tanpa filter tidak menjamin urutan apapun.

Namun, ia mengembalikan larik, yang dapat Anda urutkan Arrays.sort().

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

Ini berfungsi karena Filemerupakan kelas yang sebanding, yang secara default mengurutkan nama jalur secara leksikografis. Jika Anda ingin mengurutkan secara berbeda, Anda dapat menentukan pembanding Anda sendiri.

Jika Anda lebih suka menggunakan Stream:

Pendekatan yang lebih modern adalah sebagai berikut. Untuk mencetak nama semua file dalam direktori tertentu, dalam urutan abjad, lakukan:

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

Ganti System.out::printlndengan apa pun yang ingin Anda lakukan dengan nama file. Jika Anda hanya ingin nama file yang diakhiri dengan "xml"do:

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

Sekali lagi, ganti pencetakan dengan operasi pemrosesan mana pun yang Anda inginkan.

Ray Toal
sumber
Ini adalah satu baris kode yang indah, tetapi Arrays.sort () tampaknya mengembalikan void, bukan Iterable. Aku akan melihat-lihat sedikit.
Thunder Rabbit
3
@ Thunder Rabbit, Maafkan Aku !! Maaf, Anda benar. Saya harus mengujinya. Saya mengedit jawaban saya.
Ray Toal
Tampaknya berfungsi dengan baik di Windows, tetapi di folder Ubuntu dengan huruf kapital muncul lebih dulu daripada yang lain.
jmhostalet
5
Itulah cara yang saya harapkan untuk berhasil. Huruf kapital muncul sebelum huruf kecil di Unicode. Unix memiliki nama file yang peka huruf besar / kecil, jadi huruf besar harus didahulukan. Jika Anda menggunakan nama file yang tidak membedakan huruf besar / kecil di Windows, nama kapital dan huruf kecil akan digabungkan. Ini sepenuhnya seperti yang diharapkan. Jika Anda menginginkan cara Windows pada Unix, berikan komparator ke sort.
Ray Toal
2

Saya pikir jawaban sebelumnya adalah cara terbaik untuk melakukannya di sini adalah cara sederhana lainnya. hanya untuk mencetak hasil yang diurutkan.

 String path="/tmp";
 String[] dirListing = null;
 File dir = new File(path);
 dirListing = dir.list();
 Arrays.sort(dirListing);
 System.out.println(Arrays.deepToString(dirListing));
grepit
sumber
tolong beri komentar karena menurut Anda ini bukan jawaban yang benar. Jadi, saya bisa merevisinya sesuai.
grepit
1
-1 Saya benar-benar tidak memahami keuntungan dari mengonversi larik file menjadi larik string dan kemudian menyortir daripada hanya menyortir larik file seperti jawaban yang diterima.
zelanix
@zelanix terima kasih telah memberikan umpan balik. Saya tidak memiliki semua jawaban dan terkadang saya membuat kesalahan saat menjawab pertanyaan. Saya telah memperbarui jawabannya, maukah Anda memeriksanya dan melihat apakah ini adalah solusi yang lebih baik. Saya akan sangat menghargai jika Anda dapat mempertimbangkan kembali suara Anda. Terima kasih sebelumnya.
grepit
1
Ok, sekarang Anda membenarkan mengapa lebih sederhana jika Anda hanya ingin mencetak hasilnya jadi saya akan menghapus downvote saya.
zelanix
3
@ CPU100 saya percaya bahwa dengan menggunakan list () daripada listFiles () memberikan keuntungan karena hanya memiliki nama file tanpa path direktori induk, menghasilkan string yang lebih pendek dan waktu cpu yang lebih sedikit untuk mengurutkan / membandingkan.
Diljeet
1

Di Jawa 8:

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

Urutan terbalik:

Arrays.sort(files, (a, b) -> -a.getName().compareTo(b.getName()));
Sergei Rodionov
sumber
2
Anda dapat menggunakan kode ini juga:Arrays.sort(fList, Comparator.comparing(File::getName));
kemeja kotak
Hati-hati dengan ini. Kode ini non-deterministik dan tidak boleh digunakan sebagaimana adanya.
Tony Schwartz
0

Ini kode saya:

        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
sumber