inputStream关闭了,还有必要关闭InputStreamReader和BufferedReader吗?

Scroll Down

上次遇到产品方的一个代码,如下


1. BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(fileAbsolutePath));
2. BufferedReader br = new BufferedReader(new InputStreamReader(bufferedInputStream, StandardCharsets.UTF_8));
3. String line = null;
4. while (StrUtil.isNotBlank(line = br.readLine())){
5.	log.info("读取本地文件 [{}] , 返回内容: {}",fileName, line);
6.	result.add(line.trim());
}
br.close();

这里面有什么问题? 很多人看到后都觉得没有手动关闭输入流,会导致文件句柄泄漏,但是我问了业务同事他说这样没问题的,程序会自动关闭流的。于是我测试了一下,正常情况下确实可以,并且不会发生句柄泄漏。那么异常情况下呢?假如在第1-2之后程序有异常,并没有关闭buffer输入流,程序自然也不会关闭,这样就会导致泄漏。那么对于同事说的,如果代码正常执行,为什么不会出现泄漏问题,这跟我学过的内容不一样啊?
于是我找到了一篇文章,https://segmentfault.com/q/1010000005970993 这里说的 BufferedReader类的close方法做了一个装饰器模式,它会将内部的

InputStreamReader 手动关闭,即下方代码:
    public void close() throws IOException {
        synchronized (lock) {
			// 这里的in即指向 InputStreamReader对象
            if (in == null)
                return;
            try {
                in.close();
            } finally {
                in = null;
                cb = null;
            }
        }
    }

那么,我们打开InputStreamReader的close方法,即看到如下

    public void close() throws IOException {
	// 这里的sd对象是谁?从构造方法可以看到它就是我们的 BufferedInputStream对象包装的一个对象
        sd.close();
    }

至此,我们就清楚了,只需要调用最外层的close方法,它将自动递归式的帮我们调用close方法