Java Streams Files.lines()引发IOException。为什么?

Java Streams Files.lines()引发IOException。为什么?,java,exception-handling,functional-programming,stream,Java,Exception Handling,Functional Programming,Stream,Files.lines()返回一个流,据我所知,除非对其应用终端操作,否则不会对其进行计算。那么,为什么它要声明一个IOException。在流初始化过程中会出现什么错误,从而证明异常声明的合理性 我的用例是下面的方法。我想创建一个流,它以搜索模式从目录中的所有文件中对所有文本行进行流式处理 现在,如果Files.lines()在流计算期间遇到以意外编码格式化的文件,它将失败,并出现运行时异常。catch块不会捕获此异常。那么,为什么我需要异常处理呢 public static Stream&l

Files.lines()
返回一个
,据我所知,除非对其应用终端操作,否则不会对其进行计算。那么,为什么它要声明一个
IOException
。在
初始化过程中会出现什么错误,从而证明异常声明的合理性

我的用例是下面的方法。我想创建一个流,它以搜索模式从目录中的所有文件中对所有文本行进行流式处理

现在,如果
Files.lines()
在流计算期间遇到以意外编码格式化的文件,它将失败,并出现运行时异常。catch块不会捕获此异常。那么,为什么我需要异常处理呢

public static Stream<String> grep(Path dir, Pattern pattern) throws IOException {
    return Files.walk(dir)
            .filter(p -> !Files.isDirectory(p) && p.getFileName().toString().endsWith(".log"))
            .map(p -> {
                try {
                    return Files.lines(p);
                } catch(Exception e) {
                    return Stream.<String>empty();
                }
            }).flatMap(s -> s)
            .filter(l -> pattern.matcher(l).find());
}
publicstaticstreamgrep(路径目录,模式模式)抛出IOException{
返回文件.walk(dir)
.filter(p->!Files.isDirectory(p)和&p.getFileName().toString().endsWith(“.log”))
.map(p->{
试一试{
返回文件行(p);
}捕获(例外e){
返回Stream.empty();
}
}).flatMap(s->s)
.filter(l->pattern.matcher(l.find());
}

当在应用终端操作之前不会计算返回的流时,在Files.lines中创建流本身就是创建一个新的Files.newbuffereder,它可能引发给定的异常

我们可以在第3744-行看到这一点

公共静态流行(路径、字符集cs)引发IOException{
BufferedReader br=Files.newBufferedReader(路径,cs);//这可能引发IOException
试一试{
返回br.lines().onClose(asUncheckedRunnable(br));
}捕获(错误|运行时异常e){
试一试{
br.close();
}捕获(IOEX异常){
试一试{
e、 添加抑制(ex);
}捕获(可丢弃忽略){}
}
投掷e;
}
}

在做了一些实验之后,我发现文件已经在流初始化时打开了,因此将在调用Files::lines()时直接抛出异常。我投票结束这个问题,因为这是一个可以通过简单阅读免费提供的源代码来回答的问题。这在源代码中可能很明显,但考虑到流的惰性计算性质,API似乎违反直觉。好的,这是有道理的。如果实际读取导致问题,有没有办法防止我的方法中的流中断?如果数据集很小,那么在映射中使用Files::readAllLines和异常处理将是最简单的解决方案。如果数据集更大,那么您应该能够执行一些包装来吞下异常,但这会变得有点棘手。您计划使用串行流还是并行流?
public static Stream<String> lines(Path path, Charset cs) throws IOException {
    BufferedReader br = Files.newBufferedReader(path, cs); // this could throw IOException
    try {
        return br.lines().onClose(asUncheckedRunnable(br));
    } catch (Error|RuntimeException e) {
        try {
            br.close();
        } catch (IOException ex) {
            try {
                e.addSuppressed(ex);
            } catch (Throwable ignore) {}
        }
        throw e;
    }
}