DeflatorInputStream和DeflatorOutputStream不重建原始数据 [英] DeflatorInputStream and DeflatorOutputStream do not reconstruct the original data
问题描述
我想压缩一些数据,所以我遇到了DeflatorInputStream& DeflatorOutputStream类。但是,以下示例显示我在使用这些类时似乎无法重建原始数据。
I want to compress some data, so I came across the DeflatorInputStream & DeflatorOutputStream classes. However, the following example shows that I can't seem to reconstruct my original data when using these classes.
当我切换到ZipInputStream和ZipOutputStream时,它确实有效,但是因为我本身不需要zip文件,所以我认为通用压缩会更好。主要是我有兴趣理解为什么这个例子不起作用。
When I switch to a ZipInputStream and ZipOutputStream it does work, but since I don't need zip files per se, I thought a generic compression would be better. Mainly I'm interested in understanding why this example doesn't work.
//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类不同,输入和输出流对(显然)没有匹配的名称。
Blame historical precedent. On Unix, the function used to reverse a deflate
is called inflate
. So, unlike alot of other Java IO classes, the input and output stream pair does not have (obviously) matching names.
DeflaterOutputStream实际上并不允许你反转通货紧缩,而是在从接收器向源传递字节时对字节进行压缩。 DeflaterInputStream 也缩小,但它会在数据从源流向接收器时执行其操作。
The DeflaterOutputStream doesn't actually allow you to reverse a deflation, instead it deflates bytes as they are passed to it from a sink to a source. DeflaterInputStream also deflates, but it performs its action as data flows from the source to the sink.
为了读取未压缩的数据(膨胀)格式,你需要使用 InflaterInputStream
:
In order to read your data in uncompressed (inflated) format, you need to use an InflaterInputStream
:
InflaterInputStream inputStream = new InflaterInputStream(arrayInputStream);
此外,因为它可能无法从流中获取所有压缩数据读取
调用,需要使用循环。这样的事情:
Also, because its possible to not get all compressed data from the stream in one read
call, you need to use a loop. Something like this:
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输出流字节(或者关闭流)。
Finally, make sure to either flush your deflater output stream prior to retrieving the compressed bytes (or alternatively close the stream).
这篇关于DeflatorInputStream和DeflatorOutputStream不重建原始数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!