java - DeflatorInputStream 和 DeflatorOutputStream 不重构原始数据

标签 java compression deflate

我想压缩一些数据,所以我遇到了 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));

最佳答案

归咎于历史先例。在 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 输出流(或者关闭流)。

关于java - DeflatorInputStream 和 DeflatorOutputStream 不重构原始数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15742087/

相关文章:

linux - 如何预压缩非常大的html文件

java - libgdx - 在其他线程中做某事不起作用

java - 我应该读什么书来替代 "Head First Servlets and JSP"?

java - 监听所有请求 Tomcat

java - 如何确保 SFTP session 始终在 spring-batch 结束时关闭

compression - 快速压缩 : doesn't decompress LZ4 image

java - â® 字符在返回时转换为问号

c# - 如何在 C# 中提取 rar 文件?

compression - GZIP或DEFLATE最多可以增加文件大小?