2017-10-13 51 views
1

我有大約5到6個大文件,每個大小3 GB。我的目標是壓縮這些文件,然後使用文件servlet傳輸它。我的當前代碼需要大量的時間,導致瀏覽器上的超時會話。有沒有更好的方法來壓縮文件。是否有更好的方法來壓縮java中的大文件?

File zipFile=new File(downloadedFileLocation.getAbsolutePath()+"/Download.zip"); 
     FileOutputStream fos = new FileOutputStream(zipFile); 
     ZipOutputStream zos = new ZipOutputStream(fos); 
     for(File f:downloadedFileLocation.listFiles()) { 
      byte[] buffer = new byte[1024]; 
      ZipEntry ze= new ZipEntry(f.getName()); 
      zos.putNextEntry(ze); 
      FileInputStream in = new FileInputStream(f.getAbsolutePath()); 

      int len; 
      while ((len = in.read(buffer)) > 0) { 
       zos.write(buffer, 0, len); 
      } 

      in.close(); 
      zos.closeEntry(); 
      f.delete(); 
     } 
     zos.close(); 
     fos.close(); 

更改緩衝區大小會有什麼區別嗎?

任何人都可以建議任何更好的方式,可以更快地完成壓縮。

+0

物理說「不」。如果無法並行操作,則文件的大小和數量將呈線性關係。 – duffymo

+0

像@duffymo說的。這就是爲什麼一些網站顯示「你的下載將很快準備就緒」,然後生成並向你發送鏈接或使用一些漂亮的客戶端更新來使URL可用。 –

+1

您的緩衝區非常小(現代尺寸爲131072或更多),但不太可能產生足夠大的差異。你可能會使用'zos.setMethod(ZipOutputStream.STORED);'來避免壓縮,但你真的不應該期望能夠同步處理15GB的數據。在後臺進行壓縮,存儲結果,並讓客戶進行投票直至完成。 –

回答

3

任何人都可以提出任何更好的辦法,其中拉鍊可以做得更快

不,你不能這樣做拉拉鍊更快,但你可以做到這一點「活」。

在傳輸之前,不要將壓縮內容寫入臨時文件。直接寫入Servlet中的OutputStream

結果是壓縮的內容會在壓縮時傳輸,因此連接不會超時,並且總響應時間會縮短。

您還應該使用try-with-resources進行資源管理,並使用更新的NIO文件類以方便使用和更好的錯誤消息。

事情是這樣的:

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setContentType("application/zip"); 
    try (ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream())) { 
     for (File f : downloadedFileLocation.listFiles()) { 
      zos.putNextEntry(new ZipEntry(f.getName())); 
      Files.copy(f.toPath(), zos); 
      Files.delete(f.toPath()); 
     } 
    } 
} 

我在那裏留下的delete(),但是這取決於你在做什麼,做這件事的時候這種方式可能不恰當的。或者至少在下載完成之前不要刪除,即在for循環結束之前。

相關問題