我应该关闭 servlet 输出流吗? [复制]

Posted

技术标签:

【中文标题】我应该关闭 servlet 输出流吗? [复制]【英文标题】:Should I close the servlet outputstream? [duplicate] 【发布时间】:2010-12-22 05:38:26 【问题描述】:

可能重复:Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?

我是否负责关闭 HttpServletResponse.getOutputStream() (或 getWriter() 甚至输入流) 还是我应该把它留在容器里?

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
   throws ServletException, IOException 
    OutputStream o = response.getOutputStream();
    ... 
    o.close(); //yes/no ?

【问题讨论】:

【参考方案1】:

您确实不需要这样做。

拇指规则:如果您没有使用new SomeOutputStream() 自己创建/打开它,那么您不需要自己关闭它。例如,如果它是 new FileOutputStream("c:/foo.txt"),那么您显然需要自己关闭它。

有些人仍然这样做的原因只是为了确保不会再向响应正文写入任何内容。如果它曾经发生,那么这将在 appserver 日志中导致 IllegalStateException,但这不会影响客户端,因此客户端仍然会得到正确的响应。这也是一种更容易调试的方法,可以发现请求-响应链中的潜在问题,而这些问题您乍一看是看不到的。例如,其他东西正在将更多数据附加到响应正文中更下游的某个位置。

您在初学者中看到的另一个原因是他们只是想防止将更多数据写入响应正文。当 JSP 错误地在响应中发挥作用时,您经常会看到这种情况。他们只是忽略日志中的IllegalStateExceptions。不用说,这个特殊的目的是不好的

【讨论】:

如果您打开了另一个 InputStream 来包装它,您可能需要关闭该流,因为容器将看不到包装流,其中可能包含未提交的字节。理想情况下,如果包装流类似于 BufferedOutputStream,则您只需 flush() 即可,但我在使用 CipherOutputStream 时发现该类没有完全写入数据(我相信在这种情况下有充分的理由)。在这种情况下,有必要为客户端调用 close() 以获得正确的响应。【参考方案2】:

不,您不需要关闭它。如果你这样做了,你基本上就结束了对客户端的响应。关闭流后,在下一个请求之前,您无法向客户端发送任何其他内容。你没有打开流,所以你不必关闭它。

【讨论】:

以上是关于我应该关闭 servlet 输出流吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

处理流阅读器会关闭流吗?

Scala中有FIFO流吗?

using 子句会关闭此流吗?

关闭套接字会关闭流吗?

我应该尽可能使用并行流吗?

我应该使用线程编程来混合 2 个音频流吗?