Java 8:列出多个路径的文件

时间:2018-06-10 23:19:15

标签: java file java-8

如何在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);
}

有更好的方法可以在多条路径中进行搜索吗?或者我必须为多个路径运行相同的代码?

2 个答案:

答案 0 :(得分:3)

是的,你可以做到。假设您有List StringList<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个文件名,然后在打印前将它们展平为StringflatMap个对象。请注意,此方法涉及的附加步骤为 $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