如果我有一个目录包含很多文件(大约1000个文件)。其中一些文件名为 .processed ,而其他文件则没有。
如何仅列出10个未处理的文件。
我正在使用此代码过滤处理过的文件。
File[] inputFileList = inputDirectory.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return !pathname.getName().endsWith(".processed");
}
});
但是如果未处理文件的数量很大,这可能会导致内存错误。所以每次运行应用程序时我都需要读取有限数量的文件。
答案 0 :(得分:12)
这就是你应该使用java.nio.file的原因。使用Java 8:
final Path baseDir = Paths.get("path/to/dir");
final List<Path> tenFirstEntries;
final BiPredicate<Path, BasicFileAttributes> predicate = (path, attrs)
-> attrs.isRegularFile() && path.getFileName().endsWith(".processed");
try (
final Stream<Path> stream = Files.find(baseDir, 1, predicate);
) {
tenFirstEntries = stream.limit(10L).collect(Collectors.toList());
}
使用Java 7:
final Path baseDir = Paths.get("path/to/dir");
final List<Path> tenFirstEntries = new ArrayList<>(10);
final DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>()
{
@Override
public boolean accept(final Path entry)
{
return entry.getFileName().endsWith(".processed")
&& Files.isRegularFile(entry);
}
};
try (
final DirectoryStream<Path> stream
= Files.newDirectoryStream(baseDir, filter);
) {
final Iterator<Path> iterator = stream.iterator();
for (int i = 0; iterator.hasNext() && i < 10; i++)
tenFirstEntries.add(iterator.next());
}
与File.listFiles()
不同,java.nio.file使用延迟填充的目录条目流。
放弃File
的另一个原因。毕竟这是2015年。
答案 1 :(得分:4)
在Java 8中,您可以直接使用Files.walk()
创建Stream
Path
:
Path folder = Paths.get("...");
final int nbFilesToFound = 10;
List<Path> collect = Files.walk(folder)
.filter(p -> Files.isRegularFile(p) && !p.getFileName().toString().endsWith(".processed"))
.limit(nbFilesToFound)
.collect(Collectors.toList());
在Java 7中,如果您希望在达到要查找的文件数时文件迭代停止,则不应使用DirectoryStream.Filter
。
您可以创建SimpleFileVisitor
实现来实现它。
无论文件数量是多少,要达到这样的要求:从目录中提取与谓词匹配的特定数量的文件,使用SimpleFileVisitor
看起来比DirectoryStream.Filter
更直,更有效。
所以我认为它应该受到青睐
请参阅this duplicate中的答案,了解如何实施它。