InputStreamReader
的JavaDoc没有说明关闭基础InputStream
:
https://docs.oracle.com/javase/8/docs/api/java/io/InputStreamReader.html#close--
从类中复制的描述:Reader
关闭流并释放与其关联的所有系统资源。关闭流后,进一步的read(),ready(),mark(),reset()或skip()调用将抛出IOException。关闭之前关闭的流无效。
关闭InputStreamReader是否也会关闭底层的InputStream?
更新在:
InputStreamReader istream = new InputStreamReader(conn.getInputStream(), "UTF-8")
istream.close();
我是否需要关闭conn.getInputStream()
?
InputStreamReader
实施直接close
调用本地类的StreamDecoder
。这就是为什么我问问题(给你下来的人!)。
答案 0 :(得分:3)
正如其他答案和评论所说,答案是肯定的,它关闭了InputStream。您可以使用以下代码自己查看:
InputStream is = new FileInputStream("D:\\a.txt");
Reader r = new InputStreamReader(is);
r.close();
is.read(); // throws exception: stream is closed.
因此,如果您关闭Reader,则不需要也关闭InputStream。但是,我猜你到处都在使用try-with-resources(不是吗?;))并且在try块的末尾都会关闭InputStream和Reader。这并不重要,因为InputStream可以多次关闭;如果流已经关闭,那么它就是无操作。
如果你想避免关闭InputStream,你可以编写一个简单的包装器,它在关闭时什么都不做:
class UncloseableInputStream extends FilterInputStream {
public UncloseableInputStream(InputStream is) {
super(is);
}
public void close() {
// Do nothing.
}
}
InputStream is = new FileInputStream("D:\\a.txt");
Reader r = new InputStreamReader(new UncloseableInputStream(is));
r.close();
is.read(); // still works despite closing the reader.
答案 1 :(得分:0)
这取决于流实现。 InputStream
只是一个"界面"就close()
而言。 InputStreamReader
不会关闭界面。如果是,它将关闭底层数据资源(如文件描述符)。如果close
在实现中被覆盖并为空,则无效。
在OpenJdk StreamDecoder
中有一个方法
void implClose() throws IOException {
if(this.ch != null) {
this.ch.close();
} else {
this.in.close();
}
}
this.in
是来自解码器构造函数的InputStream:
StreamDecoder(InputStream var1, Object var2, CharsetDecoder var3) {
...
if(this.ch == null) {
this.in = var1;
...
}
...
}
以下是结束行动的示例。 ByteArrayInputStream
:
关闭ByteArrayInputStream无效。在关闭流之后可以调用此类中的方法,而不会生成IOException。
public void close() throws IOException {
}
FileInputStream
个差异:
关闭此文件输入流并释放与该流关联的所有系统资源。如果此流具有关联的通道,则通道也将关闭。关闭基础实例后,哪些接口使用它并不重要,它将被关闭。
public void close() throws IOException {
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
if (channel != null) {
channel.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}