最近做了一些有关批量压缩下载的功能,网上也找了一些资源,但都不是太全面,所以自己整理一份,已备不时之需。

直接上代码:

// 获取项目路径
      private static String WEBCLASS_PATH = Thread.currentThread().getContextClassLoader().getResource("").getPath();
      // 获取webinf路径
      private static String WEBINF_PATH = WEBCLASS_PATH.substring(0, WEBCLASS_PATH.lastIndexOf("classes"));
      // 获取upload路径
      private static String UPLOAD_PATH = WEBINF_PATH.substring(0, WEBINF_PATH.lastIndexOf("WEB-INF")) + "upload/";
 public void downloadAllFiles(HttpServletRequest request, HttpServletResponse response) {
        // 获取要下载的文件对应的信息ID-选中文件ID拼接的字符串
        String lessionIdStr = request.getParameter("fileIds");
        // 第一个文件的文件名
        String firstFileName = "";
        List<UploadFileInfo> downLoadFiles = new LinkedList<UploadFileInfo>();
        if (StringUtil.isNotEmpty(lessionIdStr)) {
            int end = lessionIdStr.lastIndexOf(",");
            if (end > 0) {
                if (end == lessionIdStr.length() - 1) {
                    lessionIdStr = lessionIdStr.substring(0, end);
                }
                String[] ids = lessionIdStr.split(",");
                for (int i = 0; i < ids.length; i++) {
                    // 循环获取每一个文件信息
                    UploadFileInfo fileInfo = uploadFileInfoService.selectByPrimaryKey(ids[i]);
                    if (fileInfo != null) {
                        downLoadFiles.add(fileInfo);
                    }
                    if (i == 0) {
                        firstFileName = fileInfo.getFileName().substring(0, fileInfo.getFileName().lastIndexOf("."));
                    }
                }
            }else {
                // 循环获取每一个文件信息
                UploadFileInfo fileInfo = uploadFileInfoService.selectByPrimaryKey(lessionIdStr);
                if (fileInfo != null) {
                    downLoadFiles.add(fileInfo);
                }
                firstFileName = fileInfo.getFileName().substring(0, fileInfo.getFileName().lastIndexOf("."));
            }
        }
        
        // 有数据可以下载 
        if (downLoadFiles.size() != 0) {
            // 进行预处理 
            preProcess(firstFileName, response);
            // 压缩处理
            writeZip(downLoadFiles);
            // 下载文件
            downFile(response);
            // 删除临时压缩文件  
            afterProcess();
        }
    }
    
    // 压缩文件输出流
    private ZipOutputStream out;
    // 临时压缩文件存储路径
    private String filePath;
    
    /**
     * 描述: 预处理
     * 参数: @param firseFileName 批量下载的第一个文件名
     * 参数: @param response     
     */
    private void preProcess(String firseFileName, HttpServletResponse response) {
        // 压缩文件名称
        String zipName = "【批量下载】" + firseFileName + "等.zip";
        filePath = UPLOAD_PATH + zipName;
        try {
            // 初始化压缩文件输出流
            out = new ZipOutputStream(new FileOutputStream(filePath));
            // 清空输出流(在迅雷下载不会出现一长窜)
            response.reset();
            //设置响应头和客户端保存文件名
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            // !!!new String(zipName.getBytes("GBK"), "8859_1") 如果文件包含中文,必须进行转换,否则下载后的文件名是乱码格式的
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(zipName.getBytes("GBK"), "8859_1"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 描述: 压缩处理
     * 参数: @param downloadFiles 批量下载的文件数据集合
     */
    private void writeZip(List<UploadFileInfo> downloadFiles) {
        byte[] buf = new byte[2048];
        int len = 0;
        try {
            for (UploadFileInfo fileInfo : downloadFiles) {
                // 获取上传文件
                File file = new File(UPLOAD_PATH.substring(0, UPLOAD_PATH.lastIndexOf("upload")) + fileInfo.getFilePath());
                if (!file.isFile()) {
                    continue;
                }
                    // 设置编码
                    out.setEncoding(System.getProperty("sun.jnu.encoding"));
                    // 设置压缩文件名称
                    ZipEntry ze = new ZipEntry(fileInfo.getFileName());
                    // 加入到输出流中
                    out.putNextEntry(ze);
                    // 对源文件进行读取并输出
                    FileInputStream fis = new FileInputStream(file);
                    while ((len = fis.read(buf)) != -1) {
                        out.write(buf, 0, len);
                    }
                    // 刷新(必须要有)
                    out.flush();
                    out.closeEntry();
                    fis.close();
            }
            if (out != null) {
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
    
    /**
     * 描述: 下载临时压缩文件
     * 参数: @param response
     */
    private void downFile(HttpServletResponse response) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                InputStream ins = new FileInputStream(filePath);
                // 放到缓冲流里面
                BufferedInputStream bins = new BufferedInputStream(ins);
                // 获取文件输出IO流
                OutputStream outs = response.getOutputStream();  
                BufferedOutputStream bouts = new BufferedOutputStream(outs);
                int bytesRead = 0;
                byte[] buffer = new byte[1024];
                // 开始向网络传输文件流   
                while ((bytesRead = bins.read(buffer)) != -1) {
                    bouts.write(buffer, 0, bytesRead);
                }
                // 这里一定要调用flush()方法 
                bouts.flush(); 
                ins.close();
                bins.close();
                outs.close();
                bouts.close();
            }
        } catch (IOException e) {   
            logger.error("文件下载出错", e);
        }   
    }
    
    /**
     * 描述: 删除临时压缩文件
     */
    private void afterProcess() {
        // 删除源文件
        File tempZip=new File(filePath);
        if(tempZip.exists()) {
            tempZip.delete();
        }
    }

效果截图:

详细配置信息可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd/

java批量下载的更多相关文章

  1. java批量下载,将多文件打包成zip格式下载

    现在的需求的: 根据产品族.产品类型,下载该产品族.产品类型下面的pic包: pic包是zip压缩文件: t_product表: 这些包以blob形式存在另一张表中: t_imagefile表: 现在 ...

  2. Java批量下载文件并zip打包

    客户需求:列表勾选需要的信息,点击批量下载文件的功能.这里分享下我们系统的解决方案:先生成要下载的文件,然后将其进行压缩,生成zip压缩文件,然后使用浏览器的下载功能即可完成批量下载的需求.以下是zi ...

  3. java批量下载文件为zip包

    批量下载文件为zip包的工具类 package com.meeno.trainsys.util; import javax.servlet.http.HttpServletRequest; impor ...

  4. Java 批量下载excel,并对excel赋值,压缩为zip文件(POI版)

    package com.neusoft.nda.servlet; import java.io.File;import java.io.FileInputStream;import java.io.F ...

  5. java+批量下载文件到指定文件夹

    需求 导出文件后存留在了服务器中,需要提供下载按钮,点击后可下载到本地:(因为涉及多个文件,下载前先将文件进行压缩,提供下载压缩文件) 效果预览 代码 主要方法 /**     * 下载生成的所有在线 ...

  6. java+批量下载大文件

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...

  7. JAVA 批量下载服务器文件到本地指定文件夹并重命名

    /** * @功能 下载文件到指定文件夹并重命名 * @param url 请求的路径 * @param filePath 文件将要保存的目录 * @param filename 保存到本地的文件名 ...

  8. Java批量文件打包下载

    经常遇到选择多个文件进行批量下载的情况,可以先将选择的所有的文件生成一个zip文件,然后再下载,该zip文件,即可实现批量下载,但是在打包过程中,常常也会出现下载过来的zip文件中里面有乱码的文件名, ...

  9. Java实现批量下载《神秘的程序员》漫画

    上周看了西乔的博客“西乔的九卦”.<神秘的程序员们>系列漫画感觉很喜欢,很搞笑.这些漫画经常出现在CSDN“程序员”杂志末页的,以前也看过一些. 后来就想下载下来,但是一张一张的点击右键“ ...

随机推荐

  1. springboot2.0application.在yml文件中添加自定义配置

    1. 在application.yml文件中添加自定义配置 app: platform: version: code: '1.0.0' 2. 定义bean类   具体格式: 其中的成员变量名称需要与配 ...

  2. python中的类变量和对象变量,以及传值传引用的探究

    http://www.cnblogs.com/gtarcoder/p/5005897.html http://www.cnblogs.com/mexh/p/9967811.html

  3. 201803-3 URL映射

    问题描述 URL 映射是诸如 Django.Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件.对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 ...

  4. Codeforces 1189D2. Add on a Tree: Revolution

    传送门 首先可以证明一颗树合法的充分必要条件是不存在某个节点的度数为 $2$ 首先它是必要的,考虑任意一条边连接的两点如果存在某一点 $x$ 度数为 $2$ ,那么说明 $x$ 还有连一条边出去,那么 ...

  5. Java 时间不一致

    1.new Date() 得到的时间?和系统相差 相差8个小时 2.eclipse控制台打印的时间与系统相差 相差8个小时 3.log4j日志的时间与与系统相差 相差8个小时 上述问题其实是同一个问题 ...

  6. ZROI2018暑期集训B班训练赛#1解题报告

    版权原因不公布题目信息 A 分析 虽然前一天搞到比较晚,考场上还是比较快的想到了正解,可惜姿势水平低被卡到了64(进入高中不知道考过多少次64了...) 这题有个比较明显且\(naive\)的做法是用 ...

  7. O060、Restore Volume 操作

    参考https://www.cnblogs.com/CloudMan6/p/5668872.html   前面我们学习了backup操作,现在我们来学习如何使用backup进行restore.   r ...

  8. kali破解ssh

    hydra,是一个非常好用的暴力破解工具,而且名字也很cool. 下面是官网上的介绍: AFP, Cisco AAA, Cisco auth, Cisco enable, CVS, Firebird, ...

  9. java实现spark常用算子之TakeSample

    import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...

  10. java面试6

    1.Redis是单线程还是多线程?为什么能支持访问量和高并发?并举例解释? 1)Redis是单线程的 2)Redis是单线程加多路IO复用 3)例子:上课老师解决同学们的提问 2.Nginx有哪些基本 ...