2017-10-13 96 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循环结束之前。

相关问题