代码之家  ›  专栏  ›  技术社区  ›  FkJ

Java servlet:文件下载损坏的问题

  •  0
  • FkJ  · 技术社区  · 15 年前

    我使用三个Servlet来提供下载文件:

    • ByteArrayDownloadServlet:用于小文件,例如来自数据库的报告或文件
    • FileDownloadServlet:用于从小到大的文件
    • MultipleFileDownloadServlet:用请求的文件创建一个zip并流式传输

    它们基于以下实现: link text

    我收到了几起关于下载损坏的投诉。问题是我无法模拟或在错误中找到模式:

    • 有时是大文件
    • 有时,当用户请求下载多个文件和一个zip文件并动态创建时
    • 有时使用较小的文件,但许多用户同时请求这些文件

    在帖子上面提到的评论中,有人报告了类似的问题,但没有解决方案。我也从这里读了很多帖子,越是接近: link text

    有没有人遇到过类似的问题,或者有一些示例代码可以使用?

    谢谢 费利佩

    @Override
    @SuppressWarnings("unchecked")    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        HttpSession session = request.getSession();
        List<File> selectedFileList = (List<File>) session.getAttribute("selectedFileList");
    
        if(selectedFileList == null)
        {
            response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, "Lista de arquivos não informada");
            return;
        }
    
        response.reset();
        response.setContentType("application/zip");        
    
        response.setHeader("Content-Disposition", "attachment; filename=\""
            + "atualizacoes_"
            + new Date().getTime() + ".zip" + "\"");
    
        ZipOutputStream output = null;
    
        try
        {
            output = new ZipOutputStream(response.getOutputStream());
    
            for(File file : selectedFileList)
            {
                InputStream input = new FileInputStream(file);
                output.putNextEntry(new ZipEntry(file.getName()));                
    
                byte[] buffer = new byte[DownloadHandler.DEFAULT_BUFFER_SIZE];
                int length;
                while((length = input.read(buffer)) > 0)
                {
                    output.write(buffer, 0, length);
                }
    
                output.closeEntry();
                input.close();
            }            
    
         output.finish();
         output.flush();
         output.close();
      }
      catch(Exception e) 
      {
          if(!(e instanceof ClientAbortException))
          {
              new ExceptionMail(getClass().getSimpleName(), e);
          }
        }
      finally
      {            
            session.removeAttribute("selectedFileList");        
      }
    
    3 回复  |  直到 8 年前
        1
  •  2
  •   BalusC    15 年前

        2
  •  0
  •   ehsavoie    12 年前

    您不应该关闭outputstream,因为它是由servlet容器管理的。 我不确定是否有同花顺。

        3
  •  0
  •   retromuz    12 年前

    在下面的代码行中有一个严重的流程。

    int length;
            while((length = input.read(buffer)) > 0)
            {
                output.write(buffer, 0, length);
            }
    

    你的“输入”是一个FileInputStream,对吗?如何确保FileInputStream在整个迭代过程中的可用字节数始终超过0个?相反,它必须写在下面。

    int length;
            while((length = input.read(buffer)) != -1)
            {
                output.write(buffer, 0, length);
            }
    
    推荐文章