res.flushBuffer()vs res.getOutputStream()。flush();
打电话有什么区别:
res.flushBuffer();
与
res.getOutputStream().flush();
这些方法是否刷新相同的缓冲区?
如果是这样,你能给我一个关于servlet容器如何管理这个缓冲区的线索吗?
如果您一直使用getOutputStream
写入正文,它们将刷新相同的缓冲区。 另一种替代方法是getWriter
用于非二进制数据。 如果你一直在使用它,那么调用res.getOutputStream().flush();
可能不会奏效。
管理缓冲区的方式是特定于实现的,但是以一个Tomcat实现为例 。 你可以看到有一些像这样的字段:
/** * The associated output buffer. */ protected OutputBuffer outputBuffer; /** * The associated output stream. */ protected CoyoteOutputStream outputStream; /** * The associated writer. */ protected CoyoteWriter writer;
调用getOutputStream()
会创建一个CoyoteOutputStream
,它使用在outputBuffer
显示的outputBuffer
字段,同样也用于getWriter()
。 所以他们都会使用那个outputBuffer
具体取决于你使用哪个。 flushBuffer
只是这样做:
@Override public void flushBuffer() throws IOException { outputBuffer.flush(); }
打电话有什么区别…
唯一显着的区别是,无论您是以文本还是二进制模式编写/写入正文,第一个版本都将起作用,而第二个版本仅适用于二进制模式输出。
这些方法是否刷新相同的缓冲区?
由于javadocs没有给出明确的答案,从技术上讲它是依赖于实现的。 然而,在实践中,对于大多数实现来说答案可能是“是”,因为很难想象有单独的缓冲区是有意义的。
在javadoc中有一些间接证据:
-
setBufferSize(int)
的javadoc说:“设置响应主体的首选缓冲区大小。” 这意味着这个缓冲区与javadoc中为flushBuffer()
引用的“缓冲区”相同。 -
flushBuffer()
的javadoc说:“对此方法的调用会自动提交响应,这意味着将写入状态代码和标题。” …这与一个有效地为一切提供缓冲的模型一致。
另外需要注意的是,servlet看到的响应对象实际上可能是一个特定于应用程序的包装器,它被插入到filter链的后面。 这样的包装器可能以与javadoc(以及servlet规范的其余部分)所说的方式不一致的方式运行。
如果是这样,你能给我一个关于servlet容器如何管理这个缓冲区的线索吗?
最好的办法是查看容器的源代码。