2013-11-04 93 views
1

我有超過100.000個文件,其中幾乎有4GB。 它的html,所以它可以壓縮70-80%。 文件範圍從200 KB到幾乎10 MB。用於大量文件的Java zip庫

我正在開發一個應用程序將文件從xml轉換爲html。 最後,應用程序會將html目錄歸檔爲一個zip文件。

我已經使用了一個叫做「copy-maven-plugin」的maven插件。這個插件的文檔非常好,而且很容易使用。插件使用的存檔功能默認爲「ant zip」,但您可以將其更改爲使用TrueZip。拆開它的對手。無論如何,我試圖包裝我的怪物文件夾兩種方式。默認的Ant zip使用43分鐘,TrueZip使用38分鐘。在我看來,這兩種方式都很重要。

然後我在我的命令行中用「zip -r archive file」試了一下,只用了4分鐘。 編輯:最近40分鐘未能獲得zip。我認爲也許4分鐘的時間可能會以一個損壞的郵編結束。

所以我想在處理這個數量的文件時,java可能不是那麼好。

有沒有人知道或有任何這類問題的經驗?

我想也許實現我自己的事情,並通過改變字節讀取大小它會幫助? 我知道你可以通過Zip4j使用ZipInputStream/ZipOutputStream來限制讀取的數據塊來創建/解壓zip文件並使用你自己的緩衝區大小,但是我沒有嘗試過。當它需要像永遠,我不能一直等待,找出;-)

作爲對zipIt.sh(拉鍊-r ...)昨晚行家調用exec以合理的時間內做的工作,但我想給java一個懷疑的好處。

更新1 我已經testet不同的方法(所有的默認壓縮級別):從Java

  1. zip4j。它只用了3分鐘。但該文件已損壞。似乎zip4j不處理這個數量的文件。
  2. Ant zip(通過maven插件)。壓縮:大約980MB。慢速:大約40分鐘
  3. 焦油+ xz從命令行。壓縮:567MB。速度差:63分鐘。
  4. 從命令行zip。壓縮:981MB。速度:40分鐘
  5. tar + bz2從命令行。壓縮:602MB。速度:13分
  6. 從命令行tar + gz。壓縮:864MB。速度:5分鐘
  7. java.util.zip.ZipOutputStream。壓縮:986MB。速度:熾烈4分18秒

tar + bz2和焦油+ gz似乎是很好的選擇,並給了我壓縮或速度是最重要的選項。

我沒有testet jdk7.0 ZipOutputStream,但因爲它似乎我可能已經解決了它。我使用64KB(64 * 1024)的讀取緩衝區,它看起來像一個魅力。看來我掘到了金子用java所有:-)

後,這是我實現

public static void main(String [] args) { 
    String outputFile = Config.getProperty(Property.ZIP_FILE); 
    String folderToAdd = Config.getProperty(Property.HTML_FOLDER); 
    Zipper.zip(outputFile, folderToAdd, 64*1024); 
} 

private static void zip(String zipFile, String sourceDirectory, int readChunk) { 

    ZipOutputStream out = null; 
    try { 

     //create byte buffer 
     byte[] buffer = new byte[readChunk]; 

     File dirObj = new File(sourceDirectory); 
     out = new ZipOutputStream(new FileOutputStream(zipFile)); 
     logger.info("Creating zip {} with read buffer '{}'", zipFile, readChunk); 
     addDir(dirObj, out, buffer); 

    } catch (IOException ioe) { 
     logger.error("IOException :" + ioe); 
    } finally { 
     IOUtils.closeQuietly(out); 
    } 

} 

private static void addDir(File dirObj, ZipOutputStream out, byte [] readChunk) throws IOException { 
    logger.debug("Zipping folder '{}'", dirObj.getName()); 
    StopWatch watch = new StopWatch(); 
    watch.start(); 

    File[] files = dirObj.listFiles(); 

    for (File file : files != null ? files : new File[0]) { 
     if (file.isDirectory()) { 
      addDir(file, out, readChunk); 
      continue; 
     } 
     FileInputStream in = null; 
     try { 
      in = new FileInputStream(file.getAbsolutePath()); 
      out.putNextEntry(new ZipEntry(file.getAbsolutePath())); 
      int len; 
      while ((len = in.read(readChunk)) > 0) { 
       out.write(readChunk, 0, len); 
      } 

     } finally { 
      out.closeEntry(); 
      IOUtils.closeQuietly(in); 
     } 
    } 
    watch.stop(); 
    logger.debug("Zipped folder {} in {} seconds.", dirObj.getName(), watch); 
} 
+0

只需4分鐘的命令行zip一定是在mye夢中。似乎每次現在需要超過20分鐘: -/ – Avec

+0

我嘗試使用上述方法7再次存檔文件。它再次花了3分多鐘。不太明白爲什麼有時需要3分鐘,而另一天可能需要20分鐘。 – Avec

回答

1

我懷疑的問題是文件本身的數量。您需要能夠操作ZIP條目而無需解包並重新打包所有條目。這可以產生顯着的差異。我預計會有10倍的差距。這可以在Java中完成,但我懷疑大多數庫不是爲此設計的。

你可以做的是從Java調用zip,如果這似乎做你想做的。一些使用命令行工具的maven插件(尤其是用於版本控制的工具)

順便說一句你可能會用tar + bz2之類的東西獲得更好的壓縮效果。這通過壓縮整個存檔而不是單獨壓縮每個文件來壓縮更多。這意味着如果不解壓縮/重新壓縮整個事物,就無法觸摸它。 (不像JAR/ZIP你可能會這樣做)

+0

這是我在使用zip4j後列出mye zip時得到的結果。壓縮警告:預計47160條目,但發現112696.它的腐敗或大部分文件是失蹤。我已經試過拉鍊(女巫是我目前所依靠的)和tar | gzip。每個人都需要很長時間。壓縮不是問題,因爲4比1是完全可以接受的。速度就是我想要解決的問題。無論如何thx :-) – Avec