在具有新 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
s 不遍历子目录。
杰弗里的答案稍微“流”变,有些人可能会觉得更容易。发布以确保完整性。
try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) {
StreamSupport.stream(files.spliterator(), false)
.sorted((o1, o2) -> {
try {
return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
} catch (IOException ex) {
...
}
})
.filter(file -> Files.isRegularFile(file))
.forEach(file -> {
});
}
在目录的 File 对象上使用 listFiles()。将数组转换为数组列表。然后使用 Collections 类上的静态排序方法和自定义 Comparator 对它们进行排序,该 Comparator 使用 Files 上的 getTotalSpace() 方法。编辑:使用 lastModified 而不是 getTotalSpace。
您可以使用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 提供对目录列表的低级访问,但没有完成任何处理,这留给调用者。在访问目录列表以进行进一步处理(例如排序)时,新的 J ava7 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)