我知道关闭或不关闭 ServletOutputStream
是之前许多问题的重点,如下所示:Should I close the servlet outputstream?或在这里:Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?或者在这里有另一个焦点:Do I need to flush the servlet outputstream?
普遍的共识似乎是不关闭它,因为从更严格的意义上讲,您并不拥有它。 (HttpServletResponse
拥有它。)
但是例如呢?这些结构:
PrintWriter out = new PrintWriter( new OutputStreamWriter( resp.getOutputStream(), MY.ENCODING ) );
现在我显然是 PrintWriter
的所有者,它有一些额外的缓冲区,至少需要刷新(并且例如通过关闭它来刷新)。
这里的普遍共识是什么?我是否需要关闭 PrintWriter
(或与此相关的任何其他此类构造。)?
编辑:也有关闭流的有效参数。值得注意的例如不想要在流上写入其他内容。与此同时,我们有 try-with-resource 构造,它可能改变情况。请参阅我的其他问题:Eclipse complaining over resource leak when not closing ServletOutputStream 这可能不会改变任何东西(我的总体感觉也是不要关闭流),但是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();
}
最佳答案
OutputStream
不是您创建的东西,您只需使用 ServletResponse.getOutputStream()
查询对它的引用。因此,如果你在它周围放置一些东西(例如OutputStreamWriter
或ZipOutputStream
),包装器流或写入器将只写入它。
关闭包装器流或编写器是否关闭底层流取决于实现,因此您不应关闭它。但由于在大多数情况下,包装器仅使用底层流来写入字节,因此刷新包装器就足够了。
在包装器需要某些终结的情况下,包装器应该(并且通常是)负责在单独的方法中提供此终结功能。例如,ZipOutputStream
提供了 finish()
方法,该方法可以完成 ZIP 输出流内容的写入,而无需关闭底层流。
总结:
您不应该关闭包装器,而是检查它是否提供了某种最终确定方法而不关闭底层流,您显然应该调用该方法。
关于java - 关闭ServletOutputStream的封装Writers/Streams,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25057422/