因此,我將通過說我的多線程程序未能輸出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。 –