2012-01-10 246 views
13
private void downloadAllRelease(HttpServletRequest request, 
     HttpServletResponse response) { 
    LoginToken tok=getToken(request, response); 
    int size = 0; 
    try { 
     ArrayList<Release> releases = manager.getReleases(tok.getUsername); 
     ZipOutputStream out = new ZipOutputStream(response.getOutputStream()); 
     for (int i=0; i<releases.size(); i++) { 
      size += releases.get(i).getFile().length; 
      out.putNextEntry(new ZipEntry(releases.get(i).getFilename())); 
      out.write(releases.get(i).getFile()); 
      out.closeEntry(); 
     } 
     response.setContentLength(size); 
     response.setContentType("application/force-download"); 
     response.setHeader("Content-Disposition","attachment;filename=release.zip"); 
     out.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

response.setContentLength()重新下载下载速度缓慢。
如果我不使用它或将其放在out.close()之后,一切仍然正常,但下载速度更快。
有人可以解释我为什么,如果有必要使用response.setContentLength()Servlet:response.setContentLength()减慢下载速度

+0

您的问题解决了我在Jetty 9中使用servlet-api-3.1时遇到的一个问题。我删除了servlet中的response.setContetLength();现在的响应时间与我之前使用Jetty版本获得的响应时间相匹配。 – faizal 2014-05-17 07:49:47

+0

@faizal很高兴能有所帮助。 – Simon 2014-05-18 08:40:30

回答

20

也许是因为你指定的尺寸比实际发送给响应的尺寸要大,webbrowser基本上会感到困惑并等待更多数据?你知道,ZIP压缩文件并减少最终的大小。

如果您无法事先有效地计算,请不要指定响应的内容长度。无论如何,servlet容器将automatically发送给chunked encoding。诚然,这会带来一些额外的开销,并使web浏览器留下未知的下载进度,但这并不要求您先缓存服务器内存中的整个响应,以便您可以获得正确的最终响应内容长度。

如果你真的计算最终响应的内容长度,你需要给它的所有写入ByteArrayOutputStream代替,然后通过其toByteArray()方法得到byte[]。真实的响应内容长度是byte[]的长度。

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ZipOutputStream out = new ZipOutputStream(baos); 
// ... 

byte[] bytes = baos.toByteArray(); 
response.setContentLength(bytes.length); 
response.getOutputStream().write(bytes); 

这只是更多的内存占用,因为所有内容都将首先存储在服务器的内存中。如果多个用户同时执行此操作,并且zip输出相对较大,那么您的服务器可能会迟早出现内存不足的风险。作为另一种替代方法,您可以使用FileOutputStream将其写入由File#createTempFile()创建的临时文件,以便您可以通过File#length()获取其大小,并使用FileInputStream将其直接流式传输到通常方式的响应中。这只是比较慢,因为你基本上将字节传输了两次。

+0

我有疑问写回应下载文件..如何在下载完成后重定向页面? – Palaniraja 2013-11-21 07:01:48

+0

@Palaniraja:只需按右上方的“Ask Question”按钮即可获得答案。 – BalusC 2013-11-21 07:36:22