我们正在开发一个需要刷新(强制压缩和发送数据) GZIPOutputStream的程序。问题是,GZIPOutputStream的flush方法并不像预期的那样工作(强制压缩和发送数据),相反,Stream等待更多的数据来进行有效的数据压缩。
当您调用finish时,数据将被压缩并通过输出流发送,但GZIPOutputStream (而不是底层流)将被关闭,因此在创建新的GZIPOutputStream之前,我们无法写入更多数据,这会耗费时间和性能。
希望有人能帮上忙。
诚挚的问候。
发布于 2010-09-04 07:11:01
我还没有尝试过这个方法,直到我们有了Java7,这个建议才会有用,但是从DeflaterOutputStream继承的GZIPOutputStream的flush()方法的文档依赖于the syncFlush argument (与Deflater#SYNC_FLUSH相关)在构造时指定的刷新模式来决定是否刷新要压缩的挂起数据。这个syncFlush参数在构造时也被GZIPOutputStream接受。
听起来您可能想使用Deflator#SYNC_FLUSH,甚至是Deflater#FULL_FLUSH,但是在深入研究之前,首先尝试使用the two-argument或the four-argument GZIPOutputStream constructor,并将true作为syncFlush参数。这将激活您想要的刷新行为。
发布于 2013-02-15 11:14:54
我没有找到工作的另一个答案。它仍然拒绝刷新,因为GZIPOutputStream使用的本机代码保留了数据。
谢天谢地,我发现有人在Apache Tomcat项目中实现了一个FlushableGZIPOutputStream。这里是神奇的部分:
@Override
public synchronized void flush() throws IOException {
if (hasLastByte) {
// - do not allow the gzip header to be flushed on its own
// - do not do anything if there is no data to send
// trick the deflater to flush
/**
* Now this is tricky: We force the Deflater to flush its data by
* switching compression level. As yet, a perplexingly simple workaround
* for
* http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
*/
if (!def.finished()) {
def.setLevel(Deflater.NO_COMPRESSION);
flushLastByte();
flagReenableCompression = true;
}
}
out.flush();
}您可以在这个jar中找到整个类(如果您使用Maven):
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>7.0.8</version>
</dependency>或者直接去抓取源代码FlushableGZIPOutputStream.java
它是在Apache-2.0许可下发布的。
发布于 2015-08-11 02:54:08
这段代码在我的应用程序中运行得很好。
public class StreamingGZIPOutputStream extends GZIPOutputStream {
public StreamingGZIPOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void deflate() throws IOException {
// SYNC_FLUSH is the key here, because it causes writing to the output
// stream in a streaming manner instead of waiting until the entire
// contents of the response are known. for a large 1 MB json example
// this took the size from around 48k to around 50k, so the benefits
// of sending data to the client sooner seem to far outweigh the
// added data sent due to less efficient compression
int len = def.deflate(buf, 0, buf.length, Deflater.SYNC_FLUSH);
if (len > 0) {
out.write(buf, 0, len);
}
}
}https://stackoverflow.com/questions/3640080
复制相似问题