我发现了几个类似的问题,但我仍然无法找到问题的答案。
我知道关闭外部流就足够了,它将关闭在线创建的内部流。
BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
br.close();
考虑下一个例子
Properties props = new Properties();
props.load(new FileInputStream(configPath));
是否应将FileInputStream
分配给变量然后显式关闭(或使用try-with-resource构造),或者Java GC会在props.load()
方法调用之后立即自动关闭它,因为没有参考资源?
答案 0 :(得分:6)
Javadoc声明
此方法返回后,指定的流仍保持打开状态。
所以是的,如果你想编写干净的代码,你应该自己关闭它。 GC最终将关闭它,如果它可以在流上调用finalize()
方法(如下所示),但是shouldn't rely on that。
始终关闭您的资源,这是确定的唯一方法。
/**
* Ensures that the <code>close</code> method of this file input stream is
* called when there are no more references to it.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
答案 1 :(得分:3)
必须强调使用像
这样的代码BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
// you likely insert actual operations on br here
br.close();
强烈建议不要使用,因为如果流构造和close()
调用之间的操作引发异常,则不会发生关闭。
您应该使用“try with resource”构造:
try(BufferedInputStream br = new BufferedInputStream(new FileInputStream(file))) {
// your actual operations on br here
}
这确保即使close()
正文中发生异常,也会调用try
。但是,此代码依赖于已知的事实,BufferedInputStream
的{{1}}方法将调用close()
的{{1}}方法,但这不会发生,直到构造FileInputStream
已完成。如果close()
的构造函数抛出异常,则不会调用BufferedInputStream
方法,因为没有对象可以调用BufferedInputStream
。
一个非常安全的解决方案是
close()
,即使close()
的构造函数抛出异常,也会关闭try(FileInputStream fis = new FileInputStream(file);
BufferedInputStream br = new BufferedInputStream(fis)) {
// your actual operations on br here
}
。这可能看起来像是一个罕见的极端情况,因为在该构造函数中唯一可能出错的是缓冲区分配,它可能抛出FileInputStream
并且在这种情况下你无论如何都会陷入深深的麻烦。
但请考虑像
这样的例子BufferedInputStream
由于OutOfMemoryError
的构造函数已经读取了标头,因此可能会抛出try(FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)) {
// your actual operations on ois here
}
,标头也可能无效,这也会导致异常。因此,还有更多可能出错的问题,并确保即使在这些情况下基础ObjectInputStream
已正确关闭也更为重要。