新しい I/O API を備えた Java 7 で、ディレクトリの内容を最終更新日で一覧表示する簡単な方法はありますか? 基本的に、最も長い間変更されていないファイルを取得するだけで済みます (最後に変更された昇順で並べ替え、最初のファイル名を取得します)。
6 に答える
それを行うための本当の「簡単な方法」はありませんが、それは可能です。
List<Path> files = new ArrayList<>();
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for(Path p : stream) {
files.add(p);
}
}
Collections.sort(files, new Comparator<Path>() {
public int compare(Path o1, Path o2) {
try {
return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
} catch (IOException e) {
// handle exception
}
}
});
これにより、変更されたファイルが最後に最も早くファイルが並べ替えられます。DirectoryStream
■サブディレクトリを反復処理しません。
ディレクトリのFileオブジェクトでlistFiles()を使用します。配列を配列リストに変換します。次に、Collectionsクラスの静的sortメソッドと、FilesのgetTotalSpace()メソッドを使用するカスタムComparatorを使用してそれらを並べ替えます。編集:getTotalSpaceの代わりにlastModifiedを使用します。
http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter)を使用して、http://docs.oracle.comを提供できます。 /javase/1.5.0/docs/api/java/io/FileFilter.html
次に、http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified()を比較すると、完了です。
パフォーマンスを気にする場合は、ファイルリストから最大/最小値の値を取得するだけで、O(n)の複雑さが得られます。
注: このソリューションには Guava が必要です。
Java IO/NIO API は、ディレクトリ リストへの低レベル アクセスを提供しますが、処理は行われず、呼び出し元に任されます。新しいJava7 NIO DirectoryStreamは、並べ替えなどのさらなる処理のためにディレクトリ リストにアクセスするときのフットプリントが最小限です。
ここに私の解決策があります: DirectoryStreamからファイルを読み取り、ストリームから(オプションで)制限されたサイズでソートされたキューを構築します。キューから最も古い/最新の要素を返します。
private void listFilesOldestFirst(final File directory, final Integer maxNumberOfFiles) {
final Builder<File> builder =
MinMaxPriorityQueue
.orderedBy(LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
if( maxNumberOfFiles != null ) {
builder.maximumSize(maxNumberOfFiles);
}
// queue with constant space, if maxNumberOfFiles is set, otherwise behaves like an unbound queue with an O(log n) penalty for insertion
final MinMaxPriorityQueue<File> oldestFiles = builder.create();
try(DirectoryStream<Path> stream = Files.newDirectoryStream(directory.toPath())) {
for(final Path p : stream) {
oldestFiles.add(p.toFile());
}
} catch (final IOException e) {
throw new RuntimeException(e);
}
final File[] fileArray = oldestFiles.toArray(new File[]{});
Arrays.sort(fileArray, oldestFiles.comparator());
// ... use fileArray
final ArrayList<File> arrayList = Lists.newArrayList(oldestFiles);
Collections.sort(arrayList, oldestFiles.comparator());
// ... use arrayList
}
これらの依存関係は、Guava MinMaxPriorityQueueおよびFileComparatorに必要です。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Files.newDirectoryStreamのfilterパラメーターも役立つ場合があります。
final Filter<Path> sampleFilter = new Filter<Path>() {
@Override
public boolean accept(final Path entry) throws IOException {
return true; // see commons-io -> FileFilterUtils
}
};
...
Files.newDirectoryStream(directory.toPath(), sampleFilter)