我知道很多以前的问题要关闭或不关闭ServletOutputStream
,例如:Should I close the servlet outputstream?或此处:Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?或其他重点:{{ 3}}
普遍的共识似乎是不来关闭它,因为你没有更严格意义上拥有它。 (HttpServletResponse
拥有它。)
但是,例如这些结构:
PrintWriter out = new PrintWriter(new OutputStreamWriter(resp.getOutputStream(),MY.ENCODING));
现在我显然是PrintWriter
的所有者,它有一些额外的缓冲区,至少需要刷新(并且通过关闭它来刷新)。
这里的普遍共识是什么?我是否需要关闭PrintWriter
(或任何其他此类构造。)
编辑:关闭流也有有效的参数。值得注意的是不想要在流上写一些其他东西。同时我们使用 try-with-resource 构造,可能改变图片。请在此处查看我的其他问题:Do I need to flush the servlet outputstream? 这个可能什么都不改变(我的一般感觉也就是不关闭流)但是 try-with-resource 首先就像以下代码一样尖叫:
try( Something out = new Something( resp.getOutputStream() ) ){
out.print( "Foo" );
}
而不是
Something out;
try {
out = new Something( resp.getOutputStream() );
out.print( "Foo" )
} finally {
if( out != null && out.isUnFlushedWhatever() ) out.flush();
}
答案 0 :(得分:2)
OutputStream
是您未创建的内容,您只需使用ServletResponse.getOutputStream()
查询对它的引用。因此,如果您在其周围放置某些内容(例如OutputStreamWriter
或ZipOutputStream
),则包装器流或编写器将只写入它。
关闭包装器流或写入器是否关闭底层流是依赖于实现的,所以不应该关闭它。但是因为在大多数情况下,包装器只使用底层流来写入字节,所以它足以刷新包装器。
如果包装器需要进行一些最终化,那么包装器应该(通常是)在单独的方法中提供此最终化功能。例如,ZipOutputStream
提供了一个finish()
方法,该方法完成了写入ZIP输出流的内容而不关闭基础流。
<强>总结强>
你不应该关闭包装器,但是检查它是否提供了一些终结方法而不关闭底层流,你应该明确地调用它。