首页 文章

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

提问于
浏览
0

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> -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

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

    它不是有缺陷的,而是放气的 .

    压缩数据时的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

    你必须看看这个例子:

    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;
        }
    
    }
    
  • 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

相关问题