วิธี File.listFiles ตามลำดับตัวอักษร?


96

ฉันมีรหัสด้านล่าง:

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

ใช้FileFilterงานได้ดี แต่listFiles()ดูเหมือนว่าจะแสดงรายการไฟล์ตามลำดับตัวอักษรย้อนกลับ มีวิธีบอกlistFile()ให้แสดงรายการไฟล์ตามลำดับตัวอักษรอย่างรวดเร็วหรือไม่?


1
แทนที่จะใช้ regex ให้ใช้.endsWith(".xml")แทน
Fred

คำตอบ:


223

listFilesวิธีการมีหรือไม่มีตัวกรองไม่รับประกันคำสั่งใด ๆ

อย่างไรก็ตามจะส่งคืนอาร์เรย์ซึ่งคุณสามารถจัดเรียงArrays.sort()ได้

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

ใช้งานได้เนื่องจากFileเป็นคลาสที่เทียบเคียงได้ซึ่งโดยค่าเริ่มต้นจะเรียงลำดับชื่อพา ธ ตามศัพท์ หากคุณต้องการจัดเรียงให้แตกต่างกันคุณสามารถกำหนดตัวเปรียบเทียบของคุณเองได้

หากคุณต้องการใช้สตรีม:

แนวทางที่ทันสมัยกว่ามีดังต่อไปนี้ ในการพิมพ์ชื่อไฟล์ทั้งหมดในไดเร็กทอรีที่กำหนดตามลำดับตัวอักษรให้ทำ:

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

แทนที่System.out::printlnด้วยสิ่งที่คุณต้องการทำด้วยชื่อไฟล์ หากคุณต้องการเฉพาะชื่อไฟล์ที่ลงท้ายด้วย"xml"do:

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

อีกครั้งแทนที่การพิมพ์ด้วยการประมวลผลใดก็ตามที่คุณต้องการ


นี่เป็นโค้ดบรรทัดเดียวที่สวยงาม แต่ Arrays.sort () ดูเหมือนจะคืนค่าเป็นโมฆะแทนที่จะเป็น Iterable ฉันจะสะกิดรอบ ๆ
Thunder Rabbit

3
@ ธันเดอร์แรบบิทขอโทษด้วย !! ขอโทษคุณพูดถูก ฉันควรจะทดสอบมัน ฉันแก้ไขคำตอบของฉัน
Ray Toal

ดูเหมือนว่าจะใช้งานได้ดีใน Windows แต่ในโฟลเดอร์ Ubuntu ที่มีตัวพิมพ์ใหญ่จะปรากฏก่อนส่วนที่เหลือ
jmhostalet

5
นั่นคือวิธีที่ฉันคาดหวังว่าจะได้ผล อักษรตัวใหญ่มาก่อนอักษรตัวพิมพ์เล็กใน Unicode Unixes มีชื่อไฟล์ที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ดังนั้นตัวพิมพ์ใหญ่จึงมาก่อน หากคุณใช้ชื่อไฟล์ที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่บน Windows ชื่อตัวพิมพ์ใหญ่และตัวพิมพ์เล็กจะผสมกัน นี่เป็นไปตามที่คาดไว้อย่างสมบูรณ์ หากคุณต้องการวิธีที่ Windows sortบนระบบปฏิบัติการยูนิกซ์จัดหาเปรียบเทียบกับ
Ray Toal

2

ฉันคิดว่าคำตอบก่อนหน้านี้เป็นวิธีที่ดีที่สุดที่จะทำที่นี่เป็นอีกวิธีง่ายๆ เพียงเพื่อพิมพ์ผลลัพธ์ที่เรียงลำดับ

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

คุณช่วยแสดงความคิดเห็นได้ไหมว่าทำไมคุณถึงคิดว่านี่ไม่ใช่คำตอบที่ถูกต้อง ดังนั้นฉันสามารถแก้ไขได้ตามนั้น
grepit

1
-1 ฉันไม่เข้าใจประโยชน์ของการแปลงอาร์เรย์ไฟล์เป็นสตริงอาร์เรย์แล้วเรียงลำดับแทนที่จะจัดเรียงอาร์เรย์ไฟล์ตามที่ได้รับคำตอบ
zelanix

@zelanix ขอบคุณที่ให้ข้อเสนอแนะ ฉันไม่มีคำตอบทั้งหมดและบางครั้งฉันก็ตอบคำถามผิดพลาด ฉันได้อัปเดตคำตอบแล้วโปรดตรวจสอบและดูว่านี่เป็นวิธีแก้ปัญหาที่ดีกว่าหรือไม่ฉันจะขอบคุณมากหากคุณสามารถพิจารณาการลงคะแนนของคุณใหม่ได้ ขอบคุณล่วงหน้า.
grepit

1
โอเคตอนนี้คุณปรับเหตุผลว่าทำไมมันง่ายกว่าถ้าคุณแค่ต้องการพิมพ์ผลลัพธ์ดังนั้นฉันจะลบการลงคะแนนของฉัน
zelanix

3
@ CPU100 ฉันเชื่อว่าการใช้ list () แทน listFiles () ให้ประโยชน์จากการมีเฉพาะชื่อไฟล์โดยไม่มีพา ธ ไดเร็กทอรีพา ธ ส่งผลให้สตริงสั้นลงและเวลา cpu ในการเรียง / เปรียบเทียบน้อยลง
Diljeet

1

ใน Java 8:

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

ลำดับย้อนกลับ:

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

2
คุณสามารถใช้รหัสนี้ได้เช่นกัน:Arrays.sort(fList, Comparator.comparing(File::getName));
plaidshirt

ระวังเรื่องนี้ด้วย รหัสนี้ไม่ได้กำหนดและไม่ควรใช้ตามที่เป็นอยู่
Tony Schwartz

0

นี่คือรหัสของฉัน:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.