Làm thế nào để File.listFiles theo thứ tự bảng chữ cái?


95

Tôi có mã như dưới đây:

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

Các FileFilterđang làm việc độc đáo, nhưng listFiles()dường như được liệt kê các file trong thứ tự chữ cái ngược lại. Có một số cách nhanh chóng để nói listFile()để liệt kê các tệp theo thứ tự bảng chữ cái?


1
Thay vì sử dụng regex, hãy sử dụng .endsWith(".xml")thay thế.
Fred

Câu trả lời:


221

Các listFilesphương pháp, có hoặc không có một bộ lọc không đảm bảo thứ tự bất kỳ.

Tuy nhiên, nó trả về một mảng mà bạn có thể sắp xếp với Arrays.sort().

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

Điều này hoạt động vì Filelà một lớp có thể so sánh, theo mặc định sắp xếp các tên đường dẫn theo từ điển. Nếu bạn muốn sắp xếp chúng khác nhau, bạn có thể xác định bộ so sánh của riêng mình.

Nếu bạn thích sử dụng Luồng:

Sau đây là một cách tiếp cận hiện đại hơn. Để in tên của tất cả các tệp trong một thư mục nhất định, theo thứ tự bảng chữ cái, hãy thực hiện:

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

Thay thế System.out::printlnbằng bất cứ điều gì bạn muốn làm với tên tệp. Nếu bạn chỉ muốn các tên tệp kết thúc bằng "xml"chỉ do:

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

Một lần nữa, hãy thay thế thao tác in bằng bất kỳ thao tác xử lý nào bạn muốn.


Đây là một dòng mã đẹp, nhưng Arrays.sort () dường như trả về giá trị void, thay vì có thể lặp lại. Tôi sẽ thăm dò một chút.
Thunder Rabbit,

3
@Thunder Rabbit, Lời xin lỗi của tôi !! Rất tiếc, bạn đã đúng. Tôi nên thử nghiệm nó. Tôi đã chỉnh sửa câu trả lời của mình.
Ray Toal

Có vẻ như nó hoạt động tốt trong Windows, nhưng trong Ubuntu, các thư mục viết hoa xuất hiện đầu tiên so với phần còn lại.
jmhostalet

5
Đó là cách tôi mong đợi nó hoạt động. Chữ in hoa đứng trước chữ thường trong Unicode. Các Unix có tên tệp phân biệt chữ hoa chữ thường, vì vậy chữ viết hoa đứng đầu tiên. Nếu bạn đang sử dụng tên tệp không phân biệt chữ hoa chữ thường trên Windows, tên viết hoa và viết thường sẽ được trộn lẫn với nhau. Điều này là hoàn toàn như mong đợi. Nếu bạn muốn chạy Windows trên Unix, hãy cung cấp bộ so sánh cho sort.
Ray Toal

2

Tôi nghĩ câu trả lời trước là cách tốt nhất để làm điều đó ở đây là một cách đơn giản khác. chỉ để in kết quả đã sắp xếp.

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

bạn vui lòng cung cấp bình luận tại sao bạn nghĩ rằng đây không phải là một câu trả lời chính xác. Vì vậy, tôi có thể sửa lại nó cho phù hợp.
grepit

1
-1 Tôi thực sự không hiểu lợi thế của việc chuyển đổi mảng tệp thành mảng chuỗi và sau đó sắp xếp thay vì chỉ sắp xếp mảng tệp như câu trả lời được chấp nhận.
zelanix

@zelanix cảm ơn bạn đã cung cấp phản hồi. Tôi không có tất cả các câu trả lời và đôi khi tôi mắc lỗi khi trả lời các câu hỏi. Tôi đã cập nhật câu trả lời, bạn vui lòng xem lại và xem đây có phải là giải pháp tốt hơn không. Tôi sẽ đánh giá cao nếu bạn có thể xem xét lại phiếu bầu của mình. Cảm ơn trước.
grepit

1
Ok, bây giờ bạn giải thích tại sao nó đơn giản hơn nếu bạn chỉ muốn in kết quả, vì vậy tôi sẽ loại bỏ phiếu phản đối của mình.
zelanix

3
@ CPU100, tôi tin rằng bằng cách sử dụng list () thay vì listFiles () mang lại lợi ích là chỉ có tên tệp mà không có đường dẫn thư mục mẹ, dẫn đến chuỗi ngắn hơn và thời gian sắp xếp / so sánh của cpu ít hơn.
Diljeet

1

Trong Java 8:

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

Đảo ngược thứ tự:

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

2
Bạn cũng có thể sử dụng mã này:Arrays.sort(fList, Comparator.comparing(File::getName));
plaidshirt

Hãy cẩn thận với điều này. Mã này là không xác định và không nên được sử dụng như hiện nay.
Tony Schwartz

0

Đây là mã của tôi:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.