InputStream
实现 Closeable
接口。
我明白,关闭尚未结束的 InputStream 可以释放一些底层资源,并且保持其开启状态可以使其他方法继续从中读取。
但是, 已经结束了的 InputStream 不关闭会有什么意义呢?
如果没有意义,为什么到达 InpuntStream 的结尾并不意味着要关闭它呢?
同样的问题也适用于 Reader
。
InputStream
实现 Closeable
接口。
我明白,关闭尚未结束的 InputStream 可以释放一些底层资源,并且保持其开启状态可以使其他方法继续从中读取。
但是, 已经结束了的 InputStream 不关闭会有什么意义呢?
如果没有意义,为什么到达 InpuntStream 的结尾并不意味着要关闭它呢?
同样的问题也适用于 Reader
。
针对您对org.life.java的评论,我的回答是:
我知道,问题是:为什么InputStream的结束不意味着close()?
因为对于某些流来说,您可以倒回并重新开始读取。对于其他一些流,例如套接字,这是不可能的,但它们必须遵守合同规则。
此外,这就是关闭流的正确方式(未显示异常处理):
InputStream stream = openMethod( );
try
{
consumeMethod( stream );
}
finally
{
stream.close( );
}
InputStream
或Reader
有子类可以倒带吗? - java.is.for.desktopmarkSupported
返回true,则可以使用mark
和reset
流位置。gpeche在他的答案中提到了这一点。 - Alexander Pogrebnyak在Windows下的一个原因是为了保持文件锁定。打开的文件无法被重命名、删除或移动。
在编程中有一个微妙的用例,即在输入流结束后不关闭它:包装流。默认情况下,关闭包装器(如FilterInputStream)将关闭底层流。有时您想停止使用包装器但继续使用底层流,因此您必须仅丢弃包装器而不调用close。
考虑以下示例:
try (InputStream in0 = new FileInputStream(...)) {
int len = (...);
// Hypothetical class `BoundedInputStream`
InputStream in1 = new BoundedInputStream(in0, len);
while (in1.read() != -1); // Discard bytes until end
// Now stop using in1 without calling close(),
// because in1.close() would trigger in0.close()
// Read more data in a different way
DataInput in2 = new DataInputStream(in0);
long x = in1.readLong(); // Reads exactly 8 bytes
// We can neglect in2 without calling close() because
// itself doesn't hold any limited resources like file handles
// Read more data in a different way
CheckedInputStream in3 = new CheckedInputStream(in0);
(...)
// Ultimately call in0.close() directly
}
您可以使用mark()
和reset()
方法标记和重置InputStream。因此,一旦到达数据的末尾,您仍然可以返回到标记的位置。想要reset()
InputStream的人可能不希望在结束时关闭它。
我不了解java中与InputStream相关的语义,但一般来说,您可能不会关闭流,因为您没有自己打开它,只是在其上工作,并依赖调用方(另一个方法)来关闭流。如果您自己打开了流,则应始终将其关闭。
隐式关闭不是很好,因为
InputStream
是一个接口而不是一个抽象类。 - gpeche