强制刷新java中的GZIPOutputStream

Hem*_*roc 18 java gzip gzipoutputstream

我们正在开发一个程序,我们需要刷新(强制压缩和发送数据)GZIPOutputStream.问题是,GZIPOutputStream的flush方法不能按预期工作(强制压缩和发送数据),而是Stream等待更多数据进行有效的数据压缩.

当您调用完成时,数据将被压缩并通过输出流发送,但GZIPOutputStream(不是基础流)将被关闭,因此我们无法写入更多数据,直到我们创建新的GZIPOutputStream,这会花费时间和性能.

希望任何人都可以提供帮助.

最好的祝福.

seh*_*seh 10

我还没有试过这种着呢,直到我们有Java 7中掌握了这些意见,将不会有用,但是对于文档GZIPOutputStreamflush()从继承的方法DeflaterOutputStream依赖于flush模式在构建时使用指定syncFlush参数(相关Deflater#SYNC_FLUSH)到决定是否刷新要压缩的待处理数据.这个syncFlush论点也在GZIPOutputStream施工时被接受.

这听起来像你想为使用Deflator#SYNC_FLUSH或者甚至Deflater#FULL_FLUSH,但挖下去,截至目前,第一次尝试与工作前两个参数四参数的GZIPOutputStream构造函数,并通过truesyncFlush论证.这将激活你想要的冲洗行为.


Ben*_* L. 10

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

值得庆幸的是,我发现有人已经将FlushableGZIPOutputStream实现为Apache Tomcat项目的一部分.这是神奇的部分:

@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();
}
Run Code Online (Sandbox Code Playgroud)

你可以在这个jar中找到整个类(如果你使用Maven):

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-coyote</artifactId>
    <version>7.0.8</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

或者只是去抓取源代码FlushableGZIPOutputStream.java

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