首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中强制刷新GZIPOutputStream

在java中强制刷新GZIPOutputStream
EN

Stack Overflow用户
提问于 2010-09-04 06:49:15
回答 6查看 10.8K关注 0票数 18

我们正在开发一个需要刷新(强制压缩和发送数据) GZIPOutputStream的程序。问题是,GZIPOutputStream的flush方法并不像预期的那样工作(强制压缩和发送数据),相反,Stream等待更多的数据来进行有效的数据压缩。

当您调用finish时,数据将被压缩并通过输出流发送,但GZIPOutputStream (而不是底层流)将被关闭,因此在创建新的GZIPOutputStream之前,我们无法写入更多数据,这会耗费时间和性能。

希望有人能帮上忙。

诚挚的问候。

EN

回答 6

Stack Overflow用户

发布于 2010-09-04 07:11:01

我还没有尝试过这个方法,直到我们有了Java7,这个建议才会有用,但是从DeflaterOutputStream继承的GZIPOutputStreamflush()方法的文档依赖于the syncFlush argument (与Deflater#SYNC_FLUSH相关)在构造时指定的刷新模式来决定是否刷新要压缩的挂起数据。这个syncFlush参数在构造时也被GZIPOutputStream接受。

听起来您可能想使用Deflator#SYNC_FLUSH,甚至是Deflater#FULL_FLUSH,但是在深入研究之前,首先尝试使用the two-argumentthe four-argument GZIPOutputStream constructor,并将true作为syncFlush参数。这将激活您想要的刷新行为。

票数 12
EN

Stack Overflow用户

发布于 2013-02-15 11:14:54

我没有找到工作的另一个答案。它仍然拒绝刷新,因为GZIPOutputStream使用的本机代码保留了数据。

谢天谢地,我发现有人在Apache Tomcat项目中实现了一个FlushableGZIPOutputStream。这里是神奇的部分:

代码语言:javascript
复制
@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):

代码语言:javascript
复制
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-coyote</artifactId>
    <version>7.0.8</version>
</dependency>

或者直接去抓取源代码FlushableGZIPOutputStream.java

它是在Apache-2.0许可下发布的。

票数 11
EN

Stack Overflow用户

发布于 2015-08-11 02:54:08

这段代码在我的应用程序中运行得很好。

代码语言:javascript
复制
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);
        }
    }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3640080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档