Java Inflater和Deflater最终会削减字符

时间:2018-03-28 17:25:02

标签: java zlib

我正在尝试创建一个小型库,这将简化InflaterDeflater的使用。这是它的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.zip.*;

public class Zlib {
    /**
     * Compresses an array of bytes using Zlib.
     * @param data The array of bytes to compress
     * @return     The compressed bytes
     */
    public static byte[] compress(byte[] data) {
        byte[] r = new byte[data.length];
        // compress the data
        Deflater zip = new Deflater();
        zip.setInput(data);
        zip.finish();
        int dl = zip.deflate(r);
        zip.end();
        // remove unnecessary bytes
        List<Byte> rm = new ArrayList<>();
        for (int i = 0; i < dl; i++) {
            rm.add(r[i]);
        }
        Byte[] ro = new Byte[0];
        ro = rm.toArray(ro);
        byte[] rb = new byte[ro.length];
        for (int i = 0; i < ro.length; i++) {
            rb[i] = ro[i];
        }
        return rb;
    }

    /**
     * Decompresses a compressed array of bytes.
     * @param data                 The compressed bytes
     * @return                     The decompressed bytes
     * @throws DataFormatException Thrown when the passed bytes are the wrong format
     */
    public static byte[] decompress(byte[] data) throws DataFormatException {
        byte[] r;
        // de-compress the data
        int size = 1024;
        boolean failed = true;
        do {
            r = new byte[size];
            Inflater zip = new Inflater();
            zip.setInput(data);
            int rl = zip.inflate(r);
            if (rl < size) {
                failed = false;
            } else {
                size += 1024;
            }
        } while (failed);
        return r;
    }
}

问题是,膨胀的输出似乎不一致。我只是想在程序本身中放松和膨胀字符串,没有文件。

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.zip.DataFormatException;

public class ZlibTest {
    public static void main(String[] args) {
        String toCompress = "Hello, compressed world!";
        try {
            System.out.println("Original String:   " + toCompress);
            byte[] compressed = Zlib.compress(toCompress.getBytes("UTF-8"));
            System.out.println("Compressed String: " + byteArrayToString(compressed));
            System.out.format("Original: %d%n", toCompress.length());
            System.out.format("Compress: %d%n", compressed.length);
            byte[] decompressed = Zlib.decompress(compressed);
            System.out.println("Decompressed Str:  " + byteArrayToString(decompressed));
        } catch (UnsupportedEncodingException | DataFormatException e) {
            e.printStackTrace();
        }
    }

    public static String byteArrayToString(byte[] a) {
        return new String(a, StandardCharsets.UTF_8);
    }
}

以上代码输出:

Original String:   Hello, compressed world!
Compressed String: x��H����QH��-(J-.NMQ(�/�
Original: 24
Compress: 24
Decompressed Str:  Hello, compressed wor                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

我注意到解压缩的字符串已被切断,并且它的末尾有很多空白字符。如果我改变了这个:

System.out.println("Decompressed Str:  " + byteArrayToString(decompressed));

进入这个:

System.out.println("Decompressed Str:  " + Arrays.toString(decompressed));
// output:
// Decompressed Str:  [72, 101, 108, 108, 111, 44, 32, 99, 111, 109, 112, 114, 101, 115, 115, 101, 100, 32, 119, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...]

这些空白字符为NUL个字符。我做错了什么?

1 个答案:

答案 0 :(得分:1)

我明白了。我决定用一种更简单的方法换掉我奇怪的数组操作方法。这是现在的代码:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.*;

public class Zlib {
    /**
     * Compresses an array of bytes using Zlib.
     * @param data The array of bytes to compress
     * @return     The compressed bytes
     */
    public static byte[] compress(byte[] data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DeflaterOutputStream outputStream = new DeflaterOutputStream(baos);
        outputStream.write(data);
        outputStream.finish();

        return baos.toByteArray();
    }

    /**
     * Decompresses a compressed array of bytes.
     * @param data                 The compressed bytes
     * @return                     The decompressed bytes
     * @throws DataFormatException Thrown when the passed bytes are the wrong format
     */
    public static byte[] decompress(byte[] data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InflaterOutputStream outputStream = new InflaterOutputStream(baos);
        outputStream.write(data);
        outputStream.finish();

        return baos.toByteArray();
    }
}