简体   繁体   English

GZIPOutputStream / GZIPInputStream中的奇怪行为

[英]Strange behavior in GZIPOutputStream/GZIPInputStream

I have reduced the strange issue in this code to the minimum. 我已将这段代码中的奇怪问题降至最低。 This program writes 128,000 times the bytes for (int)90000 into a file and then tries to read it back in. 该程序将(int)90000字节的128,000倍写入文件,然后尝试将其读回。

set zipped=false and everything works like a charm set zipped=true and everything works like a charm until the 496th chunk of 1024 bytes. 设置为zipped = false时,一切工作都像一个字符设置为zipped = true,并且一切都工作起来像一个字符,直到1024字节的第496个块为止。 At that point a single byte is lost and everything is shifted to the left by one byte (see output) 到那时,一个字节丢失了,所有内容都向左移了一个字节(请参见输出)

... ...
0 1 95 -112- which is byte code for int 90,000 0 1 95 -112-这是整数90,000的字节码
Counters: 496 126937 专柜:496 126937
1 95 -112 0- which is byte code for int 23,040,000 1 95 -112 0-这是int 23,040,000的字节码
... ...

this is the code i came up with. 这是我想出的代码。 I just can't figure out why it suddenly breaks in the middle of doing the same thing over and over. 我只是想不出为什么在一次又一次地做同一件事的过程中它突然中断。 Any help/insights/explainers much appreciated. 非常感谢任何帮助/见解/解释者。

public class TestApp7 {

static final boolean    zipped = true;
static File             theFile = null;

private static void writeZipData() throws Exception {
    FileOutputStream fos = new FileOutputStream(theFile);
    BufferedOutputStream bos = null;
    if (zipped) {
        GZIPOutputStream gzout = new GZIPOutputStream(fos);
        bos = new BufferedOutputStream(gzout);
    } else 
        bos = new BufferedOutputStream(fos);
    byte[] bs9 = RHUtilities.toByteArray((int)90000);
    for (int i=0; i<128000; i++)
        bos.write(bs9);
    bos.flush();
    bos.close();
}

private static void readZipData() throws Exception {
    byte[] buf = new byte[1024];
    int chunkCounter = 0;
    int intCounter = 0;
    FileInputStream fin = new FileInputStream(theFile);
    int rdLen = 0;
    if (zipped) {
        GZIPInputStream gin = new GZIPInputStream(fin);
        while ((rdLen = gin.read(buf)) != -1) {
            System.out.println("Counters: " + chunkCounter + " " + intCounter);
            for (int i=0; i<rdLen/4; i++) {
                byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
                intCounter++;
                System.out.print(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3]);
            }
            chunkCounter++;
        }
        gin.close();
    } else {
        while ((rdLen = fin.read(buf)) != -1) {
            System.out.println("Counters: " + chunkCounter + " " + intCounter);
            for (int i=0; i<rdLen/4; i++) {
                byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
                intCounter++;
                System.out.print(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3]);
            }
            chunkCounter++;
        }
    }
    fin.close();
}

public static void main(String args[]) {
    try {
        if (zipped)
            theFile = new File("Test.gz");
        else
            theFile = new File("Test.dat");
        writeZipData();
        readZipData();
    } catch (Throwable e) { e.printStackTrace(); }
}
}

So based on Jon's wonderful comments ... you cannot rely on .read(buffer) filling the buffer even when there are more bytes in the stream - it stops at the boundary where the BufferedOutputStream-wrapped GZIPOutputStream saved a chunk of data. 因此,基于Jon的精彩注释,即使流中有更多字节,您也不能依赖.read(buffer)填充缓冲区-它停在BufferedOutputStream包装的GZIPOutputStream保存了大块数据的边界处。 just add another read to go beyond the boundary and complete the chunk 只需添加另一个读物以超出边界并完成块

        while ((rdLen = gin.read(buf)) != -1) {
            if (rdLen<chunksize) {
                byte[] missBytes = new byte[chunksize-rdLen];
                int rdLine_miss = 0;
                if ((rdLine_miss = gin.read(missBytes)) > 0)
                    System.arraycopy(missBytes,0,buf,rdLen,rdLine_miss);
                rdLen += rdLine_miss;
            }
            for (int i=0; i<rdLen/4; i++) {
                byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
                intCounter++;
                System.out.println(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3] + " ");
            }
            chunkCounter++;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM