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

Posted

技术标签:

【中文标题】BufferedReader 和 InputStreamReader 是不是应该显式关闭?【英文标题】:Should BufferedReader and InputStreamReader be closed explicitly?BufferedReader 和 InputStreamReader 是否应该显式关闭? 【发布时间】:2018-05-01 01:10:40 【问题描述】:

我想将InputStream的内容读入String

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

流来自java.lang.Process

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

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

【问题讨论】:

javadoc for lines 似乎暗示流不会自动关闭。 不要关闭任何东西。如果关闭 BufferedReader 或 InputStreamReader,它们也会隐式关闭 InputStream。但这个责任应该由打开它的人承担(最好是在 try-with-resources 中)。此外,如果您想将整个文本读入一个字符串,请不要逐行阅读,只是为了将这些行重新组合成一个字符串。换行符没有什么特别之处,这应该意味着文件必须像这样拆分。相反,将整个文件读取为字节并使用您选择的编码将它们转换为字符。 @KlitosKyriacou 这个问题是从 2008 年开始的,已经快 10 年了 @DodgyCodeException 实际上,即使问题很旧,其中的一些答案也是最近的!其中一个答案使用 Java 9 功能。 我刚刚看到您的编辑,并认为您认为这个问题不是重复的。我撤回了我的近距离投票。 【参考方案1】:

您只需要关闭 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)

【讨论】:

我从java.lang.process so cannot use Files 获取输入流。但是试一下没问题。【参考方案2】:

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

理由:-

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

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

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

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

readAllBytes() transferTo(OutputStream out)

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

【讨论】:

以上是关于BufferedReader 和 InputStreamReader 是不是应该显式关闭?的主要内容,如果未能解决你的问题,请参考以下文章

Java读取文件创建时间和最后修改时间

java发送http请求

JAVA读取TXT文件

android+php无法上传图片?

JAVA------12.app 测试api接口

Java将网页上的js下载下来。