簡體   English   中英

在多台主機上使用Java壓縮文件壓縮文件

[英]Compress file with zip algorithm in Java on multiple hosts

我的問題是拉鏈壓縮。 我必須將文件分成幾部分並平行壓縮它們,然后以正確的順序連接部件並將zip文件另存為一個文件。 拆分文件和向主機發送部件不是問題 - 我正在使用jpvm。 我的問題是:如何拆分壓縮? 我曾嘗試使用java.util.zip.Deflater來壓縮每個部分(結果是字節數組),然后將它們寫入一個ZipOutputStream,但這似乎不起作用 - 保存到文件時壓縮已經壓縮的字節再一次。 我是否必須使用deflater壓縮每個部分,然后手動添加zip標題,一些校驗和或類似的東西? Deflater會添加任何標題嗎? 我感謝任何幫助,謝謝!

您需要使用Deflaternowrap選項來生成沒有標題或預告片的原始deflate流。 然后,您需要自己用適當的zip標題和預告片包裝原始的deflate流。

要在多個處理器上創建單個deflate流,您需要能夠使用zlib中Z_SYNC_FLUSH操作將壓縮輸出刷新到字節邊界(對於不是最后一塊的塊)。 (最后一塊將正常完成。)然后可以簡單地連接各個部分。

Java 7(但不是Java 6) 文檔使用deflate()方法的可選第四個參數來支持這一點。 可以設置為SYNC_FLUSH

以這種方式分解數據將降低壓縮,因為每個塊不能從前一個塊的歷史中受益。 這可以使用setDictionary()方法解決。 向每個線程提供要壓縮的數據以及在其之前的32K字節的未壓縮數據。 然后使用帶有setDictionary()的32K,然后使用deflate()

你可以直接使用zlib在C中看到pigz的並行壓縮示例。

一旦你有了deflate流,你可以適當地包裝它以使它成為一個zip文件。 請參閱zipnote文件格式appnote 您還需要計算未壓縮數據的CRC-32才能填寫這些字段。

不幸的是你沒有顯示你的代碼,所以我不能確定我完全理解你的代碼。 但是,據我了解你的問題,我可以推薦你以下。

  1. 檢查原始文件大小,並確定塊的大小。
  2. 開始閱讀文件,直到達到塊大小。 在閱讀時,使用ZipOutputStream將內容寫入zip。 創建帶有后綴的文件,以便稍后加入內容。 后綴應該是運行索引。 由於您要將一個文件存儲在多個zip文件中,因此每個zip使用一個條目。
  3. 在讀取zip文件時,只需根據后綴(參見前面的內容)對它們進行排序,然后讀取您唯一的條目,然后將ZipInputSteam中的字節復制到FileOutputStream

不幸的是,我並不清楚你的多個主機是什么意思。 你的意思是你的文件太大了,你可以同時在單獨的機器上創建每個拉鏈? 如果這是正確的,修改#2如下:讀取文件片段時將其內容發送到遠程主機並ZipOutputStream那里使用ZipOutputStream 要從特定點讀取文件,請使用InputStream.skip()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM