File.listFilesをアルファベット順に並べ替える方法


95

私は以下のようなコードを持っています:

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
正規表現を使用する.endsWith(".xml")代わりに、代わりに使用します。
Fred

回答:


221

このlistFilesメソッドは、フィルターの有無にかかわらず、順序を保証するものではありません。

ただし、配列で返されるため、で並べ替えることができますArrays.sort()

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

これFileは、がデフォルトでパス名を辞書順にソートする同等のクラスであるため機能します。それらを別の方法でソートする場合は、独自のコンパレータを定義できます。

Streamsを使用する場合:

より近代的なアプローチは次のとおりです。特定のディレクトリにあるすべてのファイルの名前をアルファベット順に出力するには、次のようにします。

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

System.out::printlnを、ファイル名で実行したいものに置き換えます。"xml"単に次で終わるファイル名だけが欲しい場合:

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

この場合も、印刷を希望する処理操作に置き換えます。


これは美しいコード行ですが、Arrays.sort()はIterableではなくvoidを返すようです。少しつついてみます。
サンダーラビット、

3
@サンダーラビット、お詫び!! 申し訳ありませんが、あなたは正しいです。私はそれをテストするべきでした。回答を編集しました。
Ray Toal

Windowsでは問題なく動作しているようですが、Ubuntuでは大文字のフォルダが残りのフォルダより先に表示されます。
jmhostalet 2014年

5
それは私がそれが機能すると期待する方法です。Unicodeでは、大文字が小文字の前にきます。Unixは大文字と小文字を区別するファイル名を持っているので、大文字が最初にきます。Windowsで大文字と小文字を区別しないファイル名を使用している場合、大文字と小文字の名前が混在します。これは完全に予想通りです。UnixでWindowsを使用する場合は、コンパレータをに指定しsortます。
Ray Toal 2014年

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 2013年

1
-1ファイル配列を文字列配列に変換してから並べ替える利点が、受け入れられた回答のように単にファイル配列を並べ替えるのではなく、本当にわかりません。
zelanix 14

@zelanixフィードバックを提供してくれてありがとう。私はすべての答えを持っているわけではなく、時々質問に答えるのを間違えます。回答を更新しました。確認して、これがより良い解決策であるかどうかを確認してください。投票を再検討していただければ幸いです。前もって感謝します。
グリピット2014

1
さて、結果を印刷したいだけの場合はなぜ単純なのかを正当化して、反対票を削除します。
zelanix 14

3
@ CPU100 iは、listFiles()の代わりにlist()を使用することにより、親ディレクトリパスなしでファイル名のみを使用できるという利点があり、ソート/比較する文字列が短くなり、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

これに注意してください。このコードは非決定的であるため、そのまま使用しないでください。
トニーシュワルツ

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.