异常:ZLIB输入流的意外结束



GZIPInputStreamGZIPOutputStream有问题。请阅读下面的代码(或者运行它,看看会发生什么):

def main(a: Array[String]) {
    val name = "test.dat"
    new GZIPOutputStream(new FileOutputStream(name)).write(10)
    println(new GZIPInputStream(new FileInputStream(name)).read())
}

创建文件test.dat,写入GZIP格式的单字节10,并以相同格式读取同一文件中的字节

下面是我运行它得到的结果:

Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
    at java.util.zip.InflaterInputStream.fill(Unknown Source)
    at java.util.zip.InflaterInputStream.read(Unknown Source)
    at java.util.zip.GZIPInputStream.read(Unknown Source)
    at java.util.zip.InflaterInputStream.read(Unknown Source)
    at nbt.Test$.main(Test.scala:13)
    at nbt.Test.main(Test.scala)

由于某种原因,阅读线似乎走错了方向。

我在谷歌上搜索了错误Unexpected end of ZLIB input stream,发现了一些Oracle的错误报告,这些报告是在2007-2010年左右发布的。所以我猜这个bug在某种程度上仍然存在,但我不确定我的代码是否正确,所以让我把这个贴在这里,听听你的建议。谢谢你!

您必须在GZIPOutputStream上调用close()才能尝试读取它。只有当流对象实际关闭时,才会写入文件的最后一个字节。

(这与输出堆栈中任何显式缓冲无关。流只有在你告诉它关闭时才知道压缩和写入最后一个字节。flush()没用的……虽然调用finish()而不是close()应该工作。看一下javadocs)

下面是正确的代码(Java);

package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZipTest {
    public static void main(String[] args) throws
                FileNotFoundException, IOException {
        String name = "/tmp/test";
        GZIPOutputStream gz = new GZIPOutputStream(new FileOutputStream(name));
        gz.write(10);
        gz.close();       // Remove this to reproduce the reported bug
        System.out.println(new GZIPInputStream(new FileInputStream(name)).read());
    }
}

(我没有正确地实现资源管理或异常处理/报告,因为它们与该代码的目的无关。不要把它当作"好代码"的例子。)

最新更新