我想我错过了一些非常简单的东西。我有一个字节数组,其中包含使用 Deflater 写入其中的压缩数据:
deflate(outData, 0, BLOCK_SIZE, SYNC_FLUSH)
我不只是使用 GZIPOutputStream 的原因是因为有 4 个线程(变量),每个线程都有一个数据块,每个线程在将压缩数据存储到全局字节数组之前压缩它自己的块。如果我使用 GZIPOutputStream 它会弄乱格式,因为每个小块都有一个标题和尾部,并且是它自己的 gzip 数据(我只想压缩它)。
所以最后,我得到了这个 byteArray,outData,它保存了我所有的压缩数据,但我不确定如何包装它。GZIPOutputStream 从带有未压缩数据的缓冲区写入,但该数组已全部设置。它已经被压缩了,我只是想弄清楚如何把它变成一个表格。
编辑:好的,我的措辞不好。我将它写入输出,而不是文件,以便在需要时可以重定向它。一个非常简单的例子是
cat file.txt | java Jzip | gzip -d | cmp file.txt
应该返回 0。现在的问题是,如果我按原样编写这个字节数组以输出,它只是“原始”压缩数据。我认为 gzip 需要所有这些额外的信息。
如果有替代方法,那很好。像这样的全部原因是因为我需要使用多个线程。否则我只会调用 GZIPOutputStream。
双重编辑:由于评论提供了很多很好的见解,另一种方法是我只有一堆未压缩的数据块,这些数据块最初是一个长流。如果 gzip 可以读取连接的流,如果我把这些块(并保持它们按顺序排列)并将每个块分配给一个在其自己的块上调用 GZIPOutputStream 的线程,然后获取结果并将它们连接起来。本质上,每个块现在都有标题、压缩信息和预告片。如果我将它们连接起来,gzip 会认识到这一点吗?
例子:
cat file.txt
Hello world! How are you? I'm ready to set fire to this assignment.
java Testcase < file.txt > file.txt.gz
所以我从输入中接受它。在程序内部,流被分成“Hello world!” “你好吗?” “我准备点燃这个任务”(它们不是字符串,它只是一个字节数组!这只是说明)
所以我有这三个字节块,都是未压缩的。我将这些块中的每一个都分配给一个线程,该线程使用
public static class DGZIPOutputStream extends GZIPOutputStream
{
public DGZIPOutputStream(OutputStream out, boolean flush) throws IOException
{
super(out, flush);
}
public void setDictionary(byte[] b)
{
def.setDictionary(b);
}
public void updateCRC(byte[] input)
{
crc.update(input);
}
}
如您所见,这里唯一的事情是我已将刷新设置为 SYNC_FLUSH,因此我可以正确对齐并能够设置字典。如果每个线程都使用 DGZIPOutputStream (我已经测试过,它适用于一个长时间的连续输入),并且我将这三个块连接起来(现在每个块都用标题和拖尾压缩),那么 gzip -d file.txt.gz 会工作吗?
如果这太奇怪了,请完全忽略字典。这并不重要。我只是在使用它的时候添加了它。