【问题标题】:Close Encapsulating Writers/Streams for ServletOutputStream为 ServletOutputStream 封装 Writers/Streams
【发布时间】:2014-09-23 07:27:40
【问题描述】:

我知道关闭或不关闭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();
}

【问题讨论】:

  • 如果你同意普遍的共识,知道关闭 PrintWriter 将关闭根据共识应该保持打开的底层响应流,并且知道实际需要做的是刷新,不要没有你想要的答案吗?
  • @jb:是也不是。这也是我的想法,但不关闭 ServletOutputStream 并不是一个明确的案例,以至于抛出一些额外的参数无法改变它。特别是像 try-with-resource 这样的结构现在可能会改变平衡。
  • OutputStreamWriter 委托给StreamEncoder,这可能会在关闭时做额外的工作。所以 IMO,它需要关闭。

标签: java servlets outputstream


【解决方案1】:

OutputStream 不是您创建的,您只需使用 ServletResponse.getOutputStream() 查询对它的引用。因此,如果你在它周围放置一些东西(例如 OutputStreamWriterZipOutputStream),包装器流或写入器只会写入它。

关闭包装流或编写器是否关闭底层流取决于实现,因此您不应关闭它。但由于在大多数情况下,包装器只使用底层流来写入字节,因此刷新包装器就绰绰有余了。

在包装器需要一些终结的情况下,应该(并且通常是)包装器有责任在单独的方法中提供这种终结功能。例如,ZipOutputStream 提供了一个 finish() 方法,该方法在不关闭底层流的情况下完成 ZIP 输出流的内容写入。

总结:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 2012-10-23
    相关资源
    最近更新 更多