res.flushBuffer()vs res.getOutputStream()。flush();

时间:2012-11-10 00:36:40

标签: java http web-applications servlets

致电之间的区别是什么:

res.flushBuffer();

res.getOutputStream().flush();  

这些方法是否刷新相同的缓冲区?

如果是这样,你能给我一个关于servlet容器如何管理这个缓冲区的线索吗?

2 个答案:

答案 0 :(得分:2)

如果您使用getOutputStream写入正文,则会刷新相同的缓冲区。对于非二进制数据,另一种选择是getWriter。如果您一直在使用它,那么调用res.getOutputStream().flush();可能无法正常工作。

管理缓冲区的方式是特定于实现的,但需要one of the Tomcat implementations for example。你可以看到有这样的字段:

/**
 * The associated output buffer.
 */
protected OutputBuffer outputBuffer;
/**
 * The associated output stream.
 */
protected CoyoteOutputStream outputStream;
/**
 * The associated writer.
 */
protected CoyoteWriter writer;

致电getOutputStream()会创建一个CoyoteOutputStream,其中使用outputBuffer字段,该字段同时显示getWriter()。所以他们都会使用outputBuffer,具体取决于你使用的是什么。 flushBuffer只是这样做:

@Override
public void flushBuffer()
    throws IOException {
    outputBuffer.flush();
}

答案 1 :(得分:1)

  

致电......之间的区别是什么?

唯一显着的区别是,无论您是以文本还是二进制模式编写/写入正文,第一个版本都将起作用,而第二个版本仅适用于二进制模式输出。

  

这些方法是否刷新相同的缓冲区?

由于javadoc没有给出明确的答案,从技术上讲它是依赖于实现的。然而,在实践中,对于大多数实现来说,答案可能是“是”,因为很难想象有单独的缓冲区是有意义的。

在javadoc中有一些间接证据:

  • setBufferSize(int)的javadoc说:“为响应正文设置首选缓冲区大小。”这意味着此缓冲区与flushBuffer()的javadoc中引用的“缓冲区”相同。

  • flushBuffer()的javadoc说:“对此方法的调用会自动提交响应,这意味着将写入状态代码和标题。” ...这与一个有效的缓冲区的模型一致。

另一件需要注意的是,servlet看到的响应对象实际上是一个特定于应用程序的包装器,它是在过滤器链的更上方插入的。这样的包装器可能会以与javadoc(以及servlet规范的其余部分)所说的不一致的方式运行。


  

如果是这样,你能给我一个关于servlet容器如何管理这个缓冲区的线索吗?

最好的办法是查看容器的源代码。