如何在Java 8中搜索多个路径中的文件。这些不是子/兄弟目录。例如,如果我想在路径中搜索json文件,我有:
try (Stream<Path> stream = Files.find(Paths.get(path), Integer.MAX_VALUE, (p, attrs) -> attrs.isRegularFile() && p.toString().endsWith(".json"))) {
stream.map((p) -> p.name).forEach(System.out::println);
}
有更好的方法可以在多条路径中进行搜索吗?或者我必须为多个路径运行相同的代码?
答案 0 :(得分:3)
是的,你可以做到。假设您有List
String
个List<String> paths = ...;
paths.stream().map(path -> {
try (Stream<Path> stream = Files.list(Paths.get(path))) {
return stream.filter(p -> !p.toFile().isDirectory()).filter(p -> p.toString().endsWith(".json"))
.map(Path::toString).collect(Collectors.joining("\n"));
} catch (IOException e) {
// Log your ERROR here.
e.printStackTrace();
}
return "";
}).forEach(System.out::println);
个对象的路径,您可以这样做,
paths.stream().map(path -> {
try (Stream<Path> stream = Files.walk(Paths.get(path))) {
return stream.filter(p -> !p.toFile().isDirectory()).filter(p -> p.toString().endsWith(".json"))
.map(Path::toString).collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
return Collections.emptyList();
}).flatMap(List::stream).forEach(System.out::println);
如果您需要摆脱换行符,那么也可以这样做。
.json
在此处,您可以获得List
中每条路径的所有stream
个文件名,然后在打印前将它们展平为String
个flatMap
个对象。请注意,此方法涉及的附加步骤为 $this->paginate = [
'sortWhitelist' => [
'id', 'Users.username', 'Users.email', 'payed', 'Users.partner', 'created'
]
];
$pools = $this->Pools->find('all', [
'contain' => [
'Users'
]
])->formatResults(function (\Cake\Collection\CollectionInterface $results) {
return $results->map(function ($row) {
if($row['user_id'] === -1) {
$name = $this->Names->find('all', [
'conditions' => [
'pool_id' => $row['id']
]
])->first();
$row['user']['username'] = $name->name;
$row['user']['email'] = $name->email;
$row['user']['partner'] = $name->partner_id;
}
return $row;
});
});
$pools = $this->paginate($pools);
。
答案 1 :(得分:3)
这就是flatMap
的用途。
如果Path
中有path
个实例的集合,则可以使用
paths.stream()
.flatMap(path -> {
try { return Files.find(path, Integer.MAX_VALUE,
(p, attrs) -> attrs.isRegularFile() && p.toString().endsWith(".json")); }
catch (IOException ex) { throw new UncheckedIOException(ex); }
})
.forEach(System.out::println);
由于我们必须在此处理由IOException
声明的已检查find
,因此有点笨拙。将其重新定义为UncheckedIOException
是最简单的选择,因为如果在处理流时发生I / O问题,find
返回的流将会发生什么。与the documentation of find
如果在从此方法返回后访问目录时抛出
IOException
,则它将包含在UncheckedIOException
中,该its documentation将从导致访问的方法中抛出。
所以在我们的函数中做同样的事情简化了调用者的错误处理,因为它只需要处理UncheckedIOException
。
此处无法使用try(…)
,但这正是flatMap
将消除我们这一负担的原因。正如closed所述:
在将内容放入此流后,每个映射的流都为here。
因此,一旦我们的函数返回了子流,Stream实现将为我们做正确的事。
您可以链接任意流操作来代替.forEach(System.out::println);
来处理展平流的所有元素,就像单个流一样。
如果您的输入集合包含String
而不是Path
的实例,则可以在paths.stream().map(Paths::get)
操作中添加paths.stream()
而不是flatMap
。