Java DeflatorInputStream和DeflatorOutputStream不重建原始数据

Java DeflatorInputStream和DeflatorOutputStream不重建原始数据,java,compression,deflate,Java,Compression,Deflate,我想压缩一些数据,所以我遇到了DeflatorInputStream和DeflatorOutputStream类。但是,下面的示例表明,在使用这些类时,我似乎无法重建原始数据 当我切换到ZipInputStream和ZipOutStream时,它确实可以工作,但因为我本身不需要zip文件,所以我认为通用压缩会更好。我主要感兴趣的是理解为什么这个例子不起作用 //Create some "random" data int bytesLength = 1024; byte[] bytes = new

我想压缩一些数据,所以我遇到了DeflatorInputStream和DeflatorOutputStream类。但是,下面的示例表明,在使用这些类时,我似乎无法重建原始数据

当我切换到ZipInputStream和ZipOutStream时,它确实可以工作,但因为我本身不需要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));
//创建一些“随机”数据
int字节长度=1024;
字节[]字节=新字节[字节长度];
for(int i=0;i
归咎于历史先例。在Unix上,用于反转
放气
的函数称为
充气
。因此,与许多其他Java IO类不同,输入和输出流对(显然)没有匹配的名称

DeflaterOutputStream实际上不允许您反转通缩,而是在字节从接收器传递到源时进行通缩。DeflaterInputStream也会放气,但它会在数据从源流向接收器时执行其操作

为了以未压缩(膨胀)格式读取数据,您需要使用
膨胀输入流

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输出流(或者关闭流)。

只有两个小更改使代码正常工作

//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);
如果使用平减指数InputStream,则再次压缩压缩数据。将其替换为充气机InputStream,您的代码将正常工作