关闭ServletOutputStream的封装编写器/流

时间:2014-07-31 11:09:50

标签: java servlets outputstream

我知道很多以前的问题要关闭或不关闭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();
}

1 个答案:

答案 0 :(得分:2)

OutputStream是您未创建的内容,您只需使用ServletResponse.getOutputStream()查询对它的引用。因此,如果您在其周围放置某些内容(例如OutputStreamWriterZipOutputStream),则包装器流或编写器将只写入它。

关闭包装器流或写入器是否关闭底层流是依赖于实现的,所以不应该关闭它。但是因为在大多数情况下,包装器只使用底层流来写入字节,所以它足以刷新包装器。

如果包装器需要进行一些最终化,那么包装器应该(通常是)在单独的方法中提供此最终化功能。例如,ZipOutputStream提供了一个finish()方法,该方法完成了写入ZIP输出流的内容而不关闭基础流。

<强>总结

你不应该关闭包装器,但是检查它是否提供了一些终结方法而不关闭底层流,你应该明确地调用它。