java 在InputStream结束后不关闭它有什么意义呢?

fjnneemd  于 2023-02-07  发布在  Java
关注(0)|答案(8)|浏览(264)

InputStream实现了Closeable
我理解,关闭一个还没有结束的InputStream**,可以释放一些底层资源,并且,保持它打开,可以让其他方法继续从它读取。
但是,在InputStream结束后不**关闭它有什么意义呢?
如果它没有意义,为什么到达InpuntStream的末尾并不意味着关闭呢?

  • 同样的问题也适用于Reader。*
fcg9iug3

fcg9iug31#

mark()reset()允许您在接口的某些实现中“返回”。
这在实现解析器和匹配正则表达式时非常有用,因为您通常希望使用lookahead

ss2ws0br

ss2ws0br2#

作为对您在www.example.com上评论的回应org.life.java
我知道,问题是:为什么InputStream的结尾并不意味着close()?
因为,对于某些流,你可以倒带并重新开始阅读;对于其他流,例如套接字,这是不可能的,但它们必须遵守合同规则。
此外,因为这是您应该关闭流的方式(未显示异常处理):

InputStream stream = openMethod( );

try
{
   consumeMethod( stream );
}
finally
{
   stream.close( );
}

换句话说,不管是否完全消耗了流,都应该释放获取的资源。

w8ntj3qf

w8ntj3qf3#

Windows下的一个原因可能是保持文件锁定。打开的文件不能重命名,删除或移动。

0x6upsns

0x6upsns4#

您可以mark()reset()输入流。因此,一旦到达数据末尾,您仍然可以返回到您标记的位置。希望reset()输入流的用户可能不希望它在末尾关闭。

3mpgtkmj

3mpgtkmj5#

我不知道java中InputStream的语义,但一般来说,你可能不会关闭一个流,因为你自己没有打开它,只是在它上面做了一些工作,而依赖于调用方(另一个方法)来关闭流。如果你自己打开了流,你应该总是关闭它。

egdjgwm8

egdjgwm86#

隐式关闭并不是很好,因为

  • 它只会在流到达其末尾时才执行,但情况并不总是如此(在执行过程中会发生一些异常,或者只读取文件的前几个字节),因此无论如何都必须处理这些其他情况。使用几乎总是有效的隐式close会使人们更加忘记他们的finally块。
  • 一些流可以被倒回(标记/复位)。
58wvjzkj

58wvjzkj7#

从InputStream的API判断,对于一个特定的实现来说,这样做是没有问题的,即在流结束时关闭。对于许多流来说,这可能是一个非常好的主意。

gdrx4gfi

gdrx4gfi8#

在输入流结束后不关闭它有一个微妙的用例:默认情况下,关闭 Package 器(如FilterInputStream)将关闭底层流。有时候,您希望停止使用 Package 器,但继续使用底层流,因此,您必须简单地放弃 Package 器,而不调用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
}

相关问题