215


67

ディレクトリ内のファイルのリストを取得したいのですが、最も古いファイルが最初になるようにソートしたいのです。 私の解決策は、File.listFilesを呼び出し、File.lastModifiedを基にしたリストをそのまま使用することでしたが、もっと良い方法があるのか​​どうかと思いました。

編集:私の現在の解決策は、提案されているように、匿名のコンパレータを使うことです:

File [] files = directory.listFiles();

Arrays.sort(ファイル、new Comparator(){public int compare(ファイルf1、ファイルf2){戻り値Long.valueOf(f1.lastModified())。compareTo(f2.lastModified());}});

16 Answer


92


私はあなたの解決策が唯一の賢明な方法だと思います。 ファイルのリストを取得する唯一の方法は、 File.listFiles()とドキュメンテーションは、これが返されるファイルの順序について保証をしないと述べています。 したがって、あなたは Comparatorを書く必要があります。 docs / api / java / io / File.html#lastModified()[File.lastModified()]そしてこれをファイルの配列とともにhttp://java.sun.com/javase/6/docs/に渡します。 api / java / util / Arrays.html#sort(T%5B%5D、%20java.util.Comparator)[Arrays.sort()]。


44


あなたがたくさんのファイルを持っているなら、これはより速いかもしれません。 これはdecorate-sort-undecorateパターンを使用するので、ソートアルゴリズムが2つのファイルを比較するたびにではなく、各ファイルの最終更新日が_once_のみにフェッチされます。 これは、O(n log n)からO(n)への入出力呼び出しの数を減らす可能性があります。

それはもっとコードなので、もしあなたが主にスピードに関心があり、実際には測定可能なほど速いのであればこれを使うべきです(私はチェックしていません)。

クラスPairはComparable {public long t;}を実装しています。公開ファイルf;

公開ペア(ファイルファイル){f =ファイル; t = file.lastModified(); }

public int compareTo(Object o){long u =((Pair)o).t; t <uを返す -1:t == u? 0:1 ;}};

// Obtain the array of (file, timestamp) pairs.
File [] files = directory.listFiles(); Pair [] pairs = new Pair [files.length]; for(int i = 0; i <files.length; i)のペア[i] = new Pair(files [i]);

// Sort them by timestamp.
Arrays.sort(ペア);

// Take the sorted pairs and extract only the file part, discarding the timestamp.
for(int i = 0; i <files.length; i)files [i] = pairs [i] .f;


32


Longオブジェクトをボクシングせずに、似たようなアプローチについては何ですか:

File [] files = directory.listFiles();

Arrays.sort(files、new Comparator(){public int compare(ファイルf1、ファイルf2){return Long.compare(f1.lastModified()、f2.lastModified());}});


23


http://commons.apache.org/io/[apache commons IO]を見ることもできます。これは、組み込みのhttp://commons.apache.org/proper/commons-io/javadocs/api-release/を備えています。 org / apache / commons / io / compiler / LastModifiedFileComparator.html [最後に変更されたコンパレータ]とファイルを扱うための他の多くの素晴らしいユーティリティ。


22


Java 8以降のエレガントなソリューション

File [] files = directory.listFiles(); Arrays.sort(files、Comparator.comparingLong(File :: lastModified));

'' '' '

または、降順にしたい場合は、逆にしてください。

File [] files = directory.listFiles(); Arrays.sort(ファイル、Comparator.comparingLong(File :: lastModified).reversed());


14


Java 8の場合:

Arrays.sort(files、(a、b) - > Long.compare(a.lastModified()、b.lastModified()));


10


輸入:

org.apache.commons.io.comparator.LastModifiedFileComparator
http://commons.apache.org/proper/commons-io/javadocs/api-release/index.html?org/apache/commons/io/comparator/package-summary.html[Apache Commons]

コード:

public static void main(String [] args)IOExceptionをスローします。{File directory = new File( "。"); //ディレクトリではなくファイルだけを取得するFile [] files = directory.listFiles((FileFilter)FileFileFilter.FILE);

System.out.println( "デフォルトの順序"); displayFiles(ファイル)。

Arrays.sort(ファイル、LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); System.out.println( "\ n最後に変更された昇順(LASTMODIFIED_COMPARATOR)"); displayFiles(ファイル)。

Arrays.sort(ファイル、LastModifiedFileComparator.LASTMODIFIED_REVERSE); System.out.println( "\ n最後の変更降順(LASTMODIFIED_REVERSE)"); displayFiles(ファイル)。

}


5


並べ替え中のファイルが並べ替えの実行と同時に変更または更新される場合があります。

'' '' '

Java 8

プライベートstaticリストlistFilesOldestFirst(final String directoryPath)は、IOException {try(final Stream fileStream = Files.list(Paths.get(directoryPath))){return fileStream .map(Path :: toFile).collect(Collector.toMap(Function))をスローします。 identity()、File :: lastModified).entrySet().stream().sorted(Map.Entry.comparingByValue())
//            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))  // replace the previous line with this line if you would prefer files listed newest first
.map(Map.Entry :: getKey).map(File :: toPath)// List .collect(Collectors.toList())ではなくListを使用する場合は、この行を削除してください。 }}

Java 7

プライベート静的リストlistFilesOldestFirst(final String directoryPath)は、IOExceptionをスローします。{final Collection result = Arrays.asList(new File(directoryPath).listFiles());} final Map constantLastModifiedTimes = new HashMap(); for(最終ファイルf:ファイル){constantLastModifiedTimes.put(f、f.lastModified()); Collections.sort(files、new Comparator(){public int compare(最終ファイルf1、最終ファイルf2){return constantLastModifiedTimes.get(f1).compareTo(constantLastModifiedTimes.get(f2));}});結果を返します。 }
 +
これらのソリューションは両方とも一時的なマップデータ構造を作成して、ディレクトリ内の各ファイルの最終更新日時を一定にします。 これを行う必要があるのは、ソートの実行中にファイルが更新または変更されていると、比較中に最終変更時刻が変更される可能性があるため、コンパレータがコンパレータインタフェースの一般規約の推移要件に違反するためです。

一方、ソート中にファイルが更新または変更されないことがわかっている場合は、この質問に対して送信されたその他のほとんどの回答を回避できます。


2


public String [] getDirectoryList(String path){String [] dirListing = null;ファイルdir = newファイル(パス)。 dirListing = dir.list();

Arrays.sort(dirListing、0、dirListing.length); dirListingを返す。 }


1


あなたはguava Orderingを試すことができます。

Function getLastModified = new Function(){public長時間適用(ファイルfile){return file.lastModified();} ;}};

リストorderedFiles = Ordering.natural()。onResultOf(getLastModified)。 sortedCopy(ファイル)。