2015-06-16 106 views
-1

zip4j是一個偉大的圖書館。但是在使用線程的類中使用它時遇到問題。 zip4j方法是從實現線程的類中調用的,有時(並非總是)它會使文件解壓縮,並且有時會存在擴展名爲* .zip345的左文件。此外,該過程返回net.lingala.zip4j.exception.ZipException:無法重命名修改後的zip文件。多線程zip4j

從類public方法調用zip4jProcess方法。類名是:SZipInterface.class

SZipInterface.class在線程類ex:ThreadObj.class中初始化,併爲每個線程實例化。沒有使用靜態方法。

問題的原因是什麼?你如何解決它? zip4j線程安全嗎?

方法:

private int zip4jProcess() { 
    int status = 0; 
    if (null != getInFiles() && getInFiles().length > 0) { 
     for (String file : getInFiles()) { 
      File sourceFile = new File(file); 
      ZipFile zipFile = null; 
      ZipParameters zipParams = new ZipParameters(); 
      if (getPassword() != null 
        && !getPassword().trim().equalsIgnoreCase("")) { 
       zipParams.setPassword(getPassword()); 
       zipParams.setEncryptFiles(true); 
       zipParams 
         .setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); 

      } 
      zipParams 
        .setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 

      if (sourceFile.exists()) { 
       try { 
        zipFile = new ZipFile(getZipFileName()); 
        if (zipFile.getFile().exists()) { 
         zipFile.addFile(sourceFile, zipParams); 
         if (log.isDebugEnabled()) { 
          log.debug("Adding: " + sourceFile.getName() 
            + " to " + zipFile.getFile().getName() 
            + " Pass: " + getPassword()); 
         } 
        } else { 
         zipFile.createZipFile(sourceFile, zipParams); 
         if (log.isDebugEnabled()) { 
          log.debug("Creating: " + sourceFile.getName() 
            + " to " + zipFile.getFile().getName() 
            + " Pass: " + getPassword()); 
         } 
        } 
       } catch (ZipException e) { 
        log.error(e); 
        status = 1; 
       } 
      } 
     } 
    } 

    return status; 
} 
+0

是否有一個原因,你想出了這樣的結構,而不是使用單個線程的壓縮?請注意,您可以編寫多線程代碼,其中每個線程將打包自己的zip文件。然而,在你的代碼中,你的共享資源似乎來自'getInFiles()',你的代碼不是線程安全的。 – Kayaman

+0

使用多線程的原因是爲了獲得更快的結果來生成多個文件。我可以在方法上使用同步關鍵字嗎? –

+0

你創建了多少個zip文件?正如你所看到的,多線程不是一個神奇的「讓事情變得更快」的詭計。 「同步」也不是神奇的。我建議使用單線程並學習如何正確實現多線程程序(以及它的意義,因爲在你的程序中它是沒有意義的)。 – Kayaman

回答

0

我相信,你有剩菜或uncomprossed文件可能是當多個線程試圖使用相同的zip文件(可能是在zipFile.addFile(...))的時間。

因此,請嘗試以不同的方式處理addFile,並考慮到併發性。

Their support forum表示它很棘手,目前尚不支持 - 請參閱鏈接以瞭解它的侷限性。

這可能是相當棘手的執行,如果不是不可能實現,使用加密或 特別是當壓縮文件(而不是 時只使用存儲方法,這只是源文件複製到 拉鍊沒有任何壓縮)。當前壓縮/解壓縮文件塊 取決於前一個塊。因此,如果有多個線程要讀取或寫入,則這些線程不能同時執行此過程 ,但必須等到塊n-1(如果n是當前塊的 )纔會被讀取/寫入。所以,它和在同一個線程中運行 一樣好。

將不同文件寫入不同線程的zip文件(每個 線程處理zip中的唯一文件)也會非常棘手。對於 示例:對於zip中的每個文件,AES加密都需要一個唯一編號(作爲salt 計算的一部分)。另一個例子:如果正在創建一個zip文件 並且正在添加多個文件(使用 壓縮),則第二個線程將開始將第二個文件寫入zip文件,該文件應準確知道 中的哪個位置zip文件開始寫入,並且直到 第一個線程完成寫入才能確定。

一些壓縮算法,如LZMA/LZMA2,支持多線程。 不幸的是,這些壓縮方法目前不支持Zip4j在 。

他們回覆的全文(以防帖子被刪除)。

+0

響應具體是壓縮是否支持多線程。它與OP的代碼很少有關,它顯然試圖做一些由文件名和其他這類事情決定的可怕的巫術多線程。 – Kayaman

+0

@Kayaman我明白了。引用答案的答案是:多線程可以同時讀取和寫入壓縮文件而不會被炸燬?所以我想,因爲他調用新的ZipFile(getZipFileName());他有時會以相同的文件結束,因此最終導致上述情況。糾正我,如果我錯了,但引用的塊並不僅僅意味着壓縮,是嗎? –

+0

使用臨時文件構建zip文件是否使用zip4j?我認爲臨時文件是由進程共享的。 –