【问题标题】:Java: Close after returning BufferedInputStreamJava:返回 BufferedInputStream 后关闭
【发布时间】:2021-12-13 15:35:57
【问题描述】:

我正在计划创建并返回一个 InputStream 的函数,该函数又从另一个 InputStream 读取,因为该 InputStream 的初始化并不简单,我想在多个地方使用它。考虑这个简单的例子:

private static InputStream openStream() throws IOException {
    Path path = Paths.get("/etc/passwd");
    InputStream inputStream = Files.newInputStream(path);
    return new BufferedInputStream(inputStream);
}

我将使用这个函数如下:

public static void main(String[] args) {
    try (InputStream stream = openStream()) {
        byte[] buffer = new byte[1024];
        int numBytes;
        while ((numBytes = stream.read(buffer, 0, buffer.length)) > 0) {
            System.out.printf("Just read %d bytes from stream!%n", numBytes);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是,我担心在此示例中关闭 BufferedInputStream 不会关闭其中的 InputStream。如果多次调用,这会导致孤立的文件句柄和内存泄漏吗?有什么更好的解决方案?

我能想到的一个简单解决方案是定义一个可关闭的容器类并将两个输入流放入该类。当调用close() 时,这个类会简单地关闭它所有打开的句柄。

class StreamContainer implements Closeable {

    private final InputStream[] inputStreams;

    public StreamContainer(InputStream... inputStreams) {
        this.inputStreams = inputStreams;
    }

    @Override
    public void close() throws IOException {
        for (InputStream inputStream : this.inputStreams) {
            inputStream.close();
        }
    }
}

但我想,可能会有更好的解决方案,内置机制或开发模式。或者也许应该避免这些结构?

【问题讨论】:

标签: java resources inputstream


【解决方案1】:

在这种情况下你应该阅读BufferedInputStream的代码源,这是关闭的定义

public void close() throws IOException {
    while(true) {
        byte[] buffer;
        if ((buffer = this.buf) != null) {
            if (!U.compareAndSetObject(this, BUF_OFFSET, buffer, (Object)null)) {
                continue;
            }

            InputStream input = this.in;
            this.in = null;
            if (input != null) {
                input.close();
            }

            return;
        }

        return;
    }
}

正如您在关闭 BufferedInputStream 时看到的那样,底层输入流也被关闭了。

这是关闭的文档:

public void close() 抛出 IOException 关闭此输入流并释放与该流关联的所有系统资源。一旦 流已关闭,进一步 read()、available()、reset() 或 skip() 调用将引发 IOException。关闭以前的 关闭的流没有效果。

【讨论】:

  • 谢谢。我应该先阅读文档。我刚刚看到很多代码示例,其中包含的输入流在包含之前关闭,所以我假设BufferedInputStream 不会关闭其包含的输入流。
猜你喜欢
  • 2014-02-22
  • 2017-10-15
  • 1970-01-01
  • 2012-04-06
  • 2020-02-17
  • 2014-02-12
  • 2015-04-19
  • 2012-04-27
  • 2019-09-24
相关资源
最近更新 更多