我的 DeflaterOutputStream/InputStream 代码损坏数据

My DeflaterOutputStream/InputStream code corrupting data

我有一个无法压缩数据流的简单测试用例。我生成一些随机字节的 byte[],通过 DeflaterOutputStreamflush() 流压缩它,然后反转这些操作以检索原始数组。在字节 505 处,重构流开始完全由 0x00 字节组成,我不明白为什么:

        //
        // create some random bytes
        //
        Random rng = new Random();
        int len = 5000;
        byte[] data = new byte[len];
        for (int i = 0; i < len; ++i)
            data[i] = (byte) rng.nextInt(0xff);

        //
        // write to byte[] via a deflater stream
        //
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DeflaterOutputStream os = new DeflaterOutputStream(baos, true);
        os.write(data);
        os.flush();

        //
        // read back into byte[] via an inflater stream
        //
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        InflaterInputStream is = new InflaterInputStream(bais);
        byte[] readbytes = new byte[len];
        is.read(readbytes);

        //
        // check they match (they don't, at byte 505)
        //
        for (int i = 0; i < len; ++i)
            if (data[i] != readbytes[i])
                throw new RuntimeException("Mismatch at position " + i);

源数组中的内容似乎无关紧要,它始终位于位置 505 失败。

下面是两个 byte[] 数组在它们不同区域周围的样子:

?\m·g··gWNLErZ···,··-··=·;n=··F?···13·{·rw·······\`3···f····{/····t·1·WK$·······WZ······x
?\m·g··gWNLErZ···,··-····································································
                       ^byte 505

从那时起,所有那些不可打印的字符都是 0x00。为什么会这样?我觉得我一定是误解了一些关于 Deflate/Inflate 流如何工作的基本知识。这里的真实用例是网络上的流,我认为我可以通过将 Deflate/Inflate 流插入

来轻松提高性能

当我测试这个时,is.read(readBytes) returns 505,读取的字节长度。其他 single-argument-array 流方法 return void 并保证读取或写入整个数组,但 is.read() 是不同的 API 并要求您检查实际读取的字节数。

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    System.err.println( "bais size = " + bais.available() );
    InflaterInputStream is = new InflaterInputStream(bais);
    byte[] readbytes = new byte[len];
    System.err.println( "read = " + is.read(readbytes) );  // 505

这运行时没有为我抛出错误:

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    System.err.println( "bais size = " + bais.available() );
    InflaterInputStream is = new InflaterInputStream(bais);
    byte[] readbytes = new byte[len];
    for( int total = 0, result = 0; (result = is.read(readbytes, total, len-total )) != -1; )
    {
       total += result;
       System.err.println( "reading : " + total );
       if( total == len ) break;
    }