2011-02-14 49 views
3

我正在解壓縮java中的巨大gz文件,gz文件大約2 GB,解壓縮文件大約6 GB。有時它會在合理的時間內完成(比如在10分鐘或更快的時間內)。
我有一個相當強大的盒子(8GB內存,4-cpu),有沒有辦法改進下面的代碼?或使用完全不同的庫?
另外我使用了Xms256m和Xmx4g到vm。在Java中解壓縮巨大的gz文件和性能

public static File unzipGZ(File file, File outputDir) { 
    GZIPInputStream in = null; 
    OutputStream out = null; 
    File target = null; 
    try { 
     // Open the compressed file 
     in = new GZIPInputStream(new FileInputStream(file)); 

     // Open the output file 
     target = new File(outputDir, FileUtil.stripFileExt(file.getName())); 
     out = new FileOutputStream(target); 

     // Transfer bytes from the compressed file to the output file 
     byte[] buf = new byte[1024]; 
     int len; 
     while ((len = in.read(buf)) > 0) { 
      out.write(buf, 0, len); 
     } 

     // Close the file and stream 
     in.close(); 
     out.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (in != null) { 
      try { 
       in.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
     if (out != null) { 
      try { 
       out.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
    return target; 
} 
+0

@ user121196:「數十億」和Java不匹配。如果你已經控制了系統,並且如果它是一個Un * x盒子,我會考慮在這裏調用一個外部過程。這不是很好,但有一個原因,爲什麼軟件操縱真正巨大的文件或真正的巨大數量的文件(如Git,Mercurial等)不是用Java編寫的... – Gugussee 2011-02-14 10:52:36

回答

2

我不知道默認應用了多少緩衝區,如果有的話 - 但您可能想要嘗試將輸入和輸出都打包在BufferedInputStream/BufferedOutputStream中。你也可以嘗試增加你的緩衝區大小 - 1K是一個非常小的緩衝區。嘗試使用不同的尺寸,例如16K,64K等等。當然,這些應該使得BufferedInputStream不那麼重要。

另一方面,我懷疑這不是真的問題。如果它有時在10分鐘內完成並且有時需要幾個小時,則表明發生了一些非常奇怪的事情。當它需要很長時間時,它實際上是在進步嗎?輸出文件的大小是否增加?它使用重要的CPU嗎?磁盤是否一直在使用?

一面請注意:當您在finally塊中關閉inout時,您不需要在try塊中執行此操作。

0

如果您有8個內存的演出,並且輸入文件在2個演出中,您可以嘗試使用內存映射文件。 Here是一個如何做到這一點的例子。

0

嘗試使用來自java.nio的通道,有一種方法可以將字節從一個文件傳輸到其他文件通道。那麼你不必自己複製它們。這可能會相當優化。請參閱FileInputStream.getChannel()