File.listFiles alfabetik sırayla nasıl yapılır?


95

Aşağıdaki gibi kodum var:

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

Güzel FileFilterçalışıyor, ancak listFiles()dosyaları ters alfabetik sırayla listeliyor gibi görünüyor. listFile()Dosyaları alfabetik sıraya göre listelemenin hızlı bir yolu var mı ?


1
Normal ifade kullanmak .endsWith(".xml")yerine kullanın.
Fred

Yanıtlar:


222

listFilesYöntem veya filtresiz herhangi bir sırada garanti etmez.

Bununla birlikte, sıralayabileceğiniz bir dizi döndürür Arrays.sort().

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

Bu işe yarar çünkü Filevarsayılan olarak yol adlarını sözlüksel olarak sıralayan karşılaştırılabilir bir sınıftır. Bunları farklı şekilde sıralamak isterseniz, kendi karşılaştırıcınızı tanımlayabilirsiniz.

Akışları kullanmayı tercih ederseniz:

Daha modern bir yaklaşım şu şekildedir. Belirli bir dizindeki tüm dosyaların adlarını alfabetik sırada yazdırmak için şunları yapın:

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

System.out::printlnDosya adlarıyla yapmak istediğiniz şeyle değiştirin . Yalnızca ile biten dosya adları istiyorsanız, şunları yapın "xml":

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

Yine, yazdırmayı istediğiniz işleme işlemi ile değiştirin.


Bu güzel bir kod satırıdır, ancak Arrays.sort () yinelenebilir yerine void döndürüyor gibi görünüyor. Biraz uğraşacağım.
Thunder Tavşan

3
@Thunder Tavşan, Özür Dilerim !! Çok üzgünüm haklısın Test etmeliydim. Cevabımı düzenledim.
Ray Toal

Windows'ta iyi çalışıyor gibi görünüyor, ancak Ubuntu'da büyük harfli klasörler diğerlerinden önce görünür.
jmhostalet

5
Bu şekilde çalışmasını beklerdim. Unicode'da büyük harfler küçük harflerden önce gelir. Unixlerin büyük / küçük harf duyarlı dosya adları vardır, bu nedenle büyük harfler önce gelir. Windows'ta büyük / küçük harfe duyarlı olmayan dosya adları kullanıyorsanız, büyük harfler ve küçük harfler birbirine karıştırılır. Bu tamamen beklendiği gibi. Bir Unix üzerinde Windows yolunu istiyorsanız, bir karşılaştırıcı sağlayın sort.
Ray Toal

2

Sanırım önceki cevabın bunu yapmanın en iyi yolu başka bir basit yol. sıralı sonuçları yazdırmak için.

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

Bunun neden doğru bir cevap olmadığını düşündüğünüz için yorum yapar mısınız? Yani, buna göre revize edebilirim.
grepit

1
-1 Dosya dizisini bir dizge dizisine dönüştürmenin ve sonra kabul edilen yanıtın yaptığı gibi dosya dizisini sıralamak yerine sıralamanın avantajını gerçekten anlamıyorum.
zelanix

@zelanix geri bildiriminiz için teşekkürler. Tüm cevaplara sahip değilim ve bazen soruları cevaplarken hatalar yapıyorum. Cevabı güncelledim, lütfen gözden geçirip bunun daha iyi bir çözüm olup olmadığını öğrenir misiniz? Oyunuzu tekrar gözden geçirirseniz çok sevinirim. Şimdiden teşekkürler.
grepit

1
Tamam, şimdi sadece sonuçları yazdırmak istiyorsanız neden daha basit olduğunu açıklayın, böylece olumsuz oyumu kaldırayım.
zelanix

3
@ CPU100 listFiles () yerine list () kullanmanın, sadece dosya adlarına ana dizin yolları olmadan sahip olma avantajını sağladığına inanıyorum, bu da daha kısa dizeler ve sıralama / karşılaştırma için daha az cpu süresi ile sonuçlanıyor.
Diljeet

1

Java 8'de:

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

Ters sipariş:

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

2
Bu kodu da kullanabilirsiniz:Arrays.sort(fList, Comparator.comparing(File::getName));
plaidshirt

Buna dikkat et. Bu kod deterministik değildir ve olduğu gibi kullanılmamalıdır.
Tony Schwartz

0

Bu benim kodum:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.