因此,我将通过说我的多线程程序未能输出gzip可以成功解压缩的内容作为序言,因此可能还有其他问题。但是我注意到,单线程和多线程的每个块的压缩大小完全不同。Java-针对单线程和多线程的压缩差异
在我的单线程运行中,我有一个GZIPOutputStream(System.out,true)并设置了SYNC_FLUSH。我一直从system.in中读取数据,直到缓冲区已满。你可以看到,在有一个完整的缓冲区后,我告诉压缩器写入输出,然后我调用flush。确保我强制它压缩并清除任何剩余的输出,所以当它再次写入时,它不会在缓冲区中留下任何数据。
所以它非常相似,就好像您的原始输入始终是这样的长度(因此每个块都是它自己的单独流)。
因此,在我的多线程程序中,而不是有一个GZIPOutputStream写入和刷新,我只是有一堆线程,每个都有自己的GZIPOutputStream。因此,基本上,更换一个调用部分线程
List<Future<byte[]>> results = new ArrayList<Future<byte[]>>();
bytesRead = inBytes.read(buff,0,BLOCK_SIZE);
while(bytesRead != -1)
{
offset += bytesRead;
if (offset == BLOCK_SIZE)
{
results.add(exec.submit(new workerThread(buff,offset)));
offset = 0;
}
if((bytesRead=inBytes.read(buff,offset,BLOCK_SIZE-offset)) == -1) {
results.add(exec.submit(new workerThread(buff,offset)));
}
}
在哪里,我传递的缓冲区他们压缩。我所有的线程都是
private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
private byte[] finalOut;
....
public byte[] call() {
try{
GZIPOutputStream compress = new GZIPOutputStream (bOut, true);
compress.write(input,0,size);
compress.flush();
compress.close();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(-1);
}
finalOut = bOut.toByteArray();
return finalOut;
}
我想我所做的所有事情都是给予线程的压缩工作。我没有改变任何东西。然而,当我运行我的多线程程序和hexdump的结果时,我注意到每个块通常在两个程序之间有很大差异。我使用了一个小缓冲区和小输入,所以它更容易被读取。
我的多线程程序出现crc错误,这意味着至少gzip能识别格式并开始解压缩。只是在完成时,最终结果与期望的CRC不符(例如解压缩输出的大小等)。
我老实说不知道为什么会发生这种情况。我会期待一些更明显的错误,但这个看起来很随意。这绝对是压缩。并且单线程和多线程程序之间的头几个字节(当然在头部之后)通常是相同的,所以我不认为我按乱序连接(加上executor.get()函数应该处理该字节) 。
我只是难住。我知道gzip可以解压缩连接的流。我从字面上将我的输入分成两部分并分别输出,然后将它们组合到我的单线程程序中,并解压缩得很好。
为了记录,我只是在一个带有328个“A”字符的文件上试过,所以它不是很大。该GZIPOutputStream的hexdump都可以对单个线程是
0000000 8b1f 0008 0000 0000 0000 7472 581c 0000
0000010 0000 ffff 681a 0004 0000 ffff 21a2 02e2
0000020 0000 ff00 03ff a800 5bff 5c79 0001 0000
而对于多线程它
0000000 8b1f 0008 0000 0000 0000 7472 19a4 22e0
0000010 1146 0000 ff00 03ff 7500 5f6c 80d1 0000
0000020 1f00 088b 0000 0000 0000 a200 e221 4622
0000030 0011 0000 ffff 0003 6c75 d15f 0080 0000
0000040 8b1f 0008 0000 0000 0000 21a2 02e2 0000
0000050 ff00 03ff 8a00 193b 5c21 0000 0000
他们是非常不同的。
哇,这真是太长了。对于那个很抱歉。只是非常困惑和卡住。
你能提供一个可以运行的例子吗?它看起来像你在线程之间共享缓冲区,这意味着内容可能非常随机。甚至更多,我不认为这是为每个部分创建一个新的GZIP的好主意。 –
对于两个字符串a,b,如果gzip满足unzip(gzip(a + b))= unzip(gzip(a)+ gzip(b)),那么您可以为每个零件使用新的gzip实例。我没有从快速搜索中找到任何参考,但从逻辑的角度来看,这是有道理的。因为gzip被用于分块编码,比如http。 –