我想压缩一些数据,所以我遇到了DeflatorInputStream& DeflatorOutputStream类。但是,以下示例显示在使用这些类时,我似乎无法重建原始数据。
当我切换到ZipInputStream和ZipOutputStream它确实有效,但由于我本身不需要zip文件,我认为通用压缩会更好。主要是我有兴趣理解为什么这个例子不起作用。
//Create some "random" data
int bytesLength = 1024;
byte[] bytes = new byte[bytesLength];
for(int i = 0; i < bytesLength; i++) {
bytes[i] = (byte) (i % 10);
}
//Compress the data, and write it to somewhere (a byte array for this example)
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
DeflaterOutputStream outputStream = new DeflaterOutputStream(arrayOutputStream);
outputStream.write(bytes);
//Read and decompress the data
byte[] readBuffer = new byte[5000];
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(arrayOutputStream.toByteArray());
DeflaterInputStream inputStream = new DeflaterInputStream(arrayInputStream);
int read = inputStream.read(readBuffer);
//Should hold the original (reconstructed) data
byte[] actuallyRead = Arrays.copyOf(readBuffer, read);
//Results differ - will print false
System.out.println(Arrays.equals(bytes, actuallyRead));
答案 0 :(得分:17)
责备历史先例。在Unix上,用于反转deflate
的函数称为inflate
。因此,与许多其他Java IO类不同,输入和输出流对(显然)没有匹配的名称。
DeflaterOutputStream实际上并不允许您反转通货紧缩,而是在将字节从接收器传递给源时对其进行缩小。 DeflaterInputStream 也缩小,但它会在数据从源流向接收器时执行其操作。
为了以未压缩(膨胀)格式读取您的数据,您需要使用InflaterInputStream
:
InflaterInputStream inputStream = new InflaterInputStream(arrayInputStream);
此外,由于可能无法在一次read
调用中从流中获取所有压缩数据,因此您需要使用循环。像这样:
int read;
byte[] finalBuf = new byte[0], swapBuf;
byte[] readBuffer = new byte[5012];
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(
compressed);
InflaterInputStream inputStream = new InflaterInputStream(
arrayInputStream);
while ((read = inputStream.read(readBuffer)) != -1) {
System.out.println("Intermediate read: " + read);
swapBuf = finalBuf;
finalBuf = new byte[swapBuf.length + read];
System.arraycopy(swapBuf, 0, finalBuf, 0, swapBuf.length);
System.arraycopy(readBuffer, 0, finalBuf, swapBuf.length, read);
}
最后,确保在检索压缩字节之前刷新deflater输出流(或者关闭流)。
答案 1 :(得分:1)
只有2个小改动使您的代码有效。
//Compress the data, and write it to somewhere (a byte array for this example)
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
DeflaterOutputStream outputStream = new DeflaterOutputStream(arrayOutputStream);
outputStream.write(bytes);
outputStream.close();
首先,您必须关闭()输出流。平减指数必须做出一些最后的步骤来完成他的工作。
InflaterInputStream inputStream = new InflaterInputStream(arrayInputStream);
如果使用 Deflator InputStream,则会再次压缩压缩数据。将其替换为 Inflator InputStream,您的代码将正常运行。