首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GZIPOutputStream/GZIPInputStream中的奇怪行为

GZIPOutputStream/GZIPInputStream中的奇怪行为
EN

Stack Overflow用户
提问于 2017-09-29 18:24:22
回答 1查看 151关注 0票数 0

我已经将这个代码中的奇怪问题降到了最低限度。此程序将(int)90000的字节写入文件中的128,000倍,然后尝试将其读取回文件中。

设置zipped=false,一切都像魅力集zipped=true一样工作,一切都像符咒一样工作,直到第496块1024字节。这时,一个字节丢失了,所有东西都向左移动了一个字节(参见输出)。

..。

0 1 95 -112-这是int 90,000的字节码

柜台: 496 126937

1 95 -112 0-这是int 23,040,000的字节码

..。

这就是我想出来的密码。我只是不明白为什么它突然在重复做同样的事情的过程中突然中断。任何帮助/见解/解释者都非常感激。

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-30 00:17:36

基于乔恩的精彩评论..。即使流中有更多字节,也不能依赖.read(缓冲区)填充缓冲区--它停在BufferedOutputStream包装的GZIPOutputStream保存数据块的边界处。只需添加另一个读以超出边界并完成块。

代码语言:javascript
复制
        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++;
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46494870

复制
相关文章

相似问题

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