同时压缩和下载文件性能问题

时间:2014-08-17 16:25:17

标签: java performance servlets zip

我有一个servlet在下载时压缩文件。我的问题慢进程真的很慢。我正在压缩文件coz文件将超过1GB。但下载过程非常缓慢。你会建议我什么样的改善?

package mainpackage;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class DownloadZipServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    public DownloadZipServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition",
                "attachment;filename=download.zip");

        ServletOutputStream sos;
        ZipOutputStream zos;
        InputStream fis;
        List<File> filesToDownload = new ArrayList<File>();

        filesToDownload.add(new File(getDirectory(), "download.png"));
        filesToDownload.add(new File(getDirectory(), "downloadpdf.pdf"));

        sos = response.getOutputStream();
        zos = new ZipOutputStream(sos);


        for (File fileToSend : filesToDownload) {

            ZipEntry ze = new ZipEntry(fileToSend.getName());
            zos.putNextEntry(ze);

            fis = new BufferedInputStream(new FileInputStream(fileToSend));
            byte[] buffer = new byte[131072*100];
            int readBytesCount = 0;
            while ((readBytesCount = fis.read(buffer)) >= 0) {
                zos.write(buffer, 0, readBytesCount);
            }
            fis.close();
            sos.flush();
            zos.flush();
            zos.closeEntry();
        }
        zos.close();
    }


    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

    public String getDirectory() {
        Properties prop;
        String home;
        String fileSeparator;
        String directoryName;

        prop = System.getProperties();
        home = prop.getProperty("user.dir").toString();
        fileSeparator = prop.getProperty("file.separator").toString();
        directoryName = "FileToDownload";

        return home + fileSeparator + directoryName;
    }

}

3 个答案:

答案 0 :(得分:0)

以下是您可以考虑的几件事:

1)如果可以,请将文件预先压缩为zip文件并将zip文件缓存在服务器文件系统上,这样就不会产生压缩每个请求内容的成本。

2)如果您控制客户端进行下载,您可以同时下载文件的几个块并将它们组装在客户端上,从而使您可以使客户端可用的带宽饱和。这个blog entry给出了一些背景知识。

3)尝试使用不同级别的压缩来查看哪种方法最适合您正在使用的服务器/网络/客户端配置。

答案 1 :(得分:0)

我知道所有J2EE应用程序服务器都支持基于浏览器格式压缩文件的机制。 例如,在tomcat中,您可以使用http://tomcat.apache.org/tomcat-5.5-doc/config/http.html。如果你使用tomcat APR http://tomcat.apache.org/tomcat-7.0-doc/apr.html甚至可能有更好的性能。 我使用下面的配置,它tomcat压缩javascript,css,..文件加上我有的一些重要的pdf文件。

<Connector compressableMimeType="text/html,text/xml,text/javascript,text/css,application/javascript,application/pdf" compression="on" compressionMinSize="2048" connectionTimeout="20000" noCompressionUserAgents="gozilla, traviata" port="8085" protocol="HTTP/1.1" redirectPort="8443"/>   

我使用的是tomcat 7,但我确信它也适用于其他应用服务器上的其他版本

答案 2 :(得分:-1)

这种缓慢是由压缩级别引起的。默认zipoutstream压缩级别设置为-1。我不知道它的(-1压缩级别)含义但我们可以将压缩级别从零设置为9(0-9)。

zos.setLevel(0);

我添加了这个方法来获得零压缩率。现在,我的压缩和同时向客户端发送数据非常快。