2013-04-01 21 views
8

我想压缩一些数据,所以我碰到了DeflatorInputStream & DeflatorOutputStream类。但是,下面的示例显示,在使用这些类时,似乎无法重建我的原始数据。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)); 

回答

13

怪罪的历史先例。在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

只有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); 

如果使用平减指数的InputStream,你再压缩的压缩数据。将其替换为充气器 InputStream和您的代码将正常工作。