BufferedReader 和 InputStreamReader 是否应该显式关闭?

Should BufferedReader and InputStreamReader be closed explicitly?

我想把InputStream的内容读成String:

private String readToString(InputStream stream) {
    return new BufferedReader(new InputStreamReader(stream))
            .lines().collect(Collectors.joining("\n"));
}

流来自java.lang.Process

问题:在这种情况下,我是否必须明确关闭任何 InputStreamInputStreamReaderBufferedReader

旁注:链接的问题 NOT 重复,因为我的问题是关于 如何 正确关闭流,而不是如何将流读取为字符串!

您只需要关闭 outer 包装器,但不要以任何一种方式明确地这样做 - 有 try-with-resource 可以让您的生活更轻松:

public String readToString(InputStream stream) {

    try (InputStreamReader reader = new InputStreamReader(stream);
            BufferedReader br = new BufferedReader(reader)) {

        return br.lines().collect(Collectors.joining("\n"));

    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

还有一种更简单、更清晰的方法:

Files.readAllLines(YourPath)

根据我的评论,关闭 BufferedReader 或 InputStreamReader 将导致关闭 InputStream。您的 readToString 方法不应关闭流。这是来电者的责任。

理由:-

首先,请考虑在调用 readToString 之前如何打开流。一个明智的做法是:

try (InputStream myStream = getInputStreamSomehow()) {
    //...
    String content = readToString(myStream);
    //...
}

流将在您的 try-with-resources 块结束时关闭。

其次,考虑现有的最佳实践和习语。查看 Java API 方法,就像您的方法一样,读取流的全部内容。例如,从 Java 9:

以上方法都没有关闭流。同样,使用您的 readToString 方法的用户不会期望您关闭他们的流。