inflater不会解压缩所有压缩字节

时间:2016-03-09 11:14:55

标签: java zip compression

Deflater压缩包含0到99之间字节的字节数组(长度为100) 压缩的字节数组作为解压缩输入传递给Inflater。 解压缩器返回的长度缺少原始列表中的3个字节。

以下是代码:

        byte orig[] = new byte[100];
        IntStream.range(0, 100).forEach(i -> orig[i] = (byte) i);


        System.out.println("OrigLength: " + orig.length);

        byte[] compressed = new byte[orig.length];


        Deflater deflater = new Deflater();
        deflater.setInput(orig);
        deflater.finish();
        int compressedLength = deflater.deflate(compressed);
        deflater.end();
        System.out.println("--------------------------------------------------------------------");
        System.out.println("CompressedLength::" + compressedLength);
        for (int i = 0; i < compressedLength; i++) {
            System.out.print(compressed[i] + " ");
        }


        Inflater decompresser = new Inflater();
        decompresser.setInput(compressed, 0, compressedLength);
        byte[] result = new byte[compressedLength];
        int resultLength = decompresser.inflate(result);
        decompresser.end();

        System.out.println("\n--------------------------------------------------------------------");
        System.out.println("DecompressedLength::" + resultLength);
        for (int i = 0; i < resultLength; i++) {
            System.out.print(result[i] + " ");
        }

        System.out.println("\n--------------------------------------------------------------------");

输出:

  

OrigLength:100

           

CompressedLength :: 100

     

120 -100 99 96 100 98 102 97 101 99 -25 -32 -28 -30 -26 -31 -27 -29 23   16 20 18 22 17 21 19 -105 -112 -108 -110 -106 -111 -107 -109 87 80 84   82 86 81 85 83 -41 -48 -44 -46 -42 -47 -43 -45 55 48 52 50 54 49 53 51   -73 -80 -76 -78 -74 -79 -75 -77 119 112 116 114 118 113 117 115 -9 -16 -12 -14&gt; -10 -15 -11 -13 15 8 12 10 14 9 13 11 -113 -120 -116 -118 -114 -119 -115 -117 79 72

           

DecompressedLength :: 97

     

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26   27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49   50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72   73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95   96

           

处理完成,退出代码为0

解压缩长度为97,原始长度为100.您能否建议我的代码有什么问题?

感谢。

3 个答案:

答案 0 :(得分:1)

虽然不清楚,但我发现了以下内容,

有效的不是充气器,而是散热器。

压缩数据时的Deflater我惊奇地注意到字节数比原始未压缩数据增加。例如,上面的压缩数据数组有100个元素,因为数组的大小为100。

但是,如果我增加压缩数组大小(任意说200)然后使用该数组,那么deflate方法将返回一个值108(这里比原始100多8个字节)。这令我感到困惑,因为我理解我需要知道什么是deflate压缩以及算法是如何工作的,我正在经历它。

所以这是更新后的代码,

byte orig[] = new byte[100];

        IntStream.range(0, 100).forEach(i -> orig[i] = (byte) i);

        System.out.println("OrigLength: " + orig.length);

        byte[] compressed = new byte[orig.length * 2]; // double it arbitrarily chosen 


        Deflater deflater = new Deflater();
        deflater.setInput(orig);
        deflater.finish();
        int compressedLength = 0;
        compressedLength = deflater.deflate(compressed);
        deflater.end();
        System.out.println("--------------------------------------------------------------------");
        System.out.println("CompressedLength::" + compressedLength); //now this will be 108
        for (int i = 0; i < compressedLength; i++) {
            System.out.print(compressed[i] + " ");
        }


        Inflater decompresser = new Inflater();
        byte[] result = new byte[orig.length];
        decompresser.setInput(compressed, 0, compressedLength);
        int resultLength  = decompresser.inflate(result);
        decompresser.end();

        System.out.println("\n--------------------------------------------------------------------");
        System.out.println("DecompressedLength::" + resultLength);
        for (int i = 0; i < resultLength; i++) {
            System.out.print(result[i] + " ");
        }

        System.out.println("\n--------------------------------------------------------------------");

输出:

OrigLength:100

CompressedLength :: 108 //这是关注点8字节额外

120 -100 99 96 100 98 102 97 101 99 -25 -32 -28 -30 -26 -31 -27 -29 23 16 20 18 22 17 21 19 -105 -112 -108 -110 -106 -111 -107 -109 87 80 84 82 86 81 85 83 -41 -48 -44 -46 -42 -47 -43 -45 55 48 52 50 54 49 53 51 -73 -80 -76 -78 -74 -79 -75 -77 119 112 116 114 118 113 117 115 -9 -16 -12 -14 -10 -15 -11 -13 15 8 12 10 14 9 13 11 -113 -120 -116 -118 -114 -119 -115 -117 79 72 76 74 6 0 -117 124 19 87

DecompressedLength :: 100

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

答案 1 :(得分:0)

你必须看看这个例子:

https://github.com/DawnScience/dawn-common/blob/master/org.dawb.common.util/src/org/dawb/common/util/list/PrimitiveArrayEncoder.java#L95

public static String compress(final String expanded) {

    try {
        byte[] input = expanded.getBytes("US-ASCII");

        // Compress the bytes
        byte[] output = new byte[input.length];
        Deflater compresser = new Deflater();
        compresser.setInput(input);
        compresser.finish();
        final int size  = compresser.deflate(output);

        return new String(output, 0, size, "US-ASCII");
    } catch (Exception ne) {
        ne.printStackTrace();
        return null;
    }
}

/**
 * Inflate a string
 * @param compressed
 * @return Inflated string.
 */
public static String expand(final String compressed) {

    try {
        final byte[] output = compressed.getBytes("US-ASCII");

        // Decompress the bytes
        Inflater decompresser = new Inflater();
        decompresser.setInput(output, 0, output.length);

        byte[] result = new byte[output.length*2];
        int resultLength = decompresser.inflate(result);
        decompresser.end();

        // Decode the bytes into a String
        return new String(result, 0, resultLength, "US-ASCII");

    } catch (Exception ne) {
        ne.printStackTrace();
        return null;
    }

}

答案 2 :(得分:0)

您可以在这里找到一些想法:

private static byte[] readCompressed(final Repository db,
        final AnyObjectId id) throws FileNotFoundException, IOException {
    final FileInputStream objStream = new FileInputStream(db.toFile(id));
    final byte[] compressed;
    try {
        compressed = new byte[objStream.available()];
        int off = 0;
        while (off < compressed.length)
            off += objStream.read(compressed, off, compressed.length - off);
    } finally {
        objStream.close();
    }
    return compressed;
}

此处的完整代码: http://code.openhub.net/file?fid=50oAEc5CLFonr_2GPq0IoqxVPw8&cid=6SVb15jezXE&s=inflater%20does%20not%20decompress%20all%20the%20compressed%20bytes&pp=0&fl=Java&ff=1&projSelected=false&filterChecked,=true&mp,=1&filterChecked=true&mp=1&ml=1&me=1&md=1#L26