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

直接上代码:

// 获取项目路径
      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. PAT B1042 挖掘机哪家强

    AC代码 #include <cstdio> #include <algorithm> using namespace std; const int max_n = 11000 ...

  2. ThinkPHP开发api时多级控制器的访问方法

    发开api时,经常会用到thinkphp的多级控制器,访问方法如下: 例如:有v1和v2两个版本的接口 v1:版本控制器(类文件位置为:application/api/controller/v1/Us ...

  3. golang作用域问题

    //参考 https://segmentfault.com/a/1190000012214571 //参考 https://studygolang.com/articles/2215 func bar ...

  4. WPF的硬件加速

    wpf根据硬件 可以做出三档的渲染 dx7以下 第0档  不支持硬件加速 dx7-dx9 第1档, 不支持所有硬件加速,但支持一部分 dx9 以上 支持所有硬件加速 可以用编程的方式取代 当前设备处于 ...

  5. Linux Too many open files

    Linux Too many open files 查看系统资源限制信息: sudo -s -u root -H id sudo -s lsof | awk '{ print $2 " &q ...

  6. java中成员变量和局部变量在内存中的分配

    对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量:局部变量就是方法或语句块内部定义的变量.局部变量必须初始化. 形式参数是局部变量,局部变量中基础数据类型的引用和值都存储在栈中,对象引 ...

  7. centos 配置rsync+inotify数据实时同步

    何为rsync? 定义: rsync是一个开源的快速备份工具,可以在不同主机之间镜像同步整个目录树,支持增量备份,保持链接和权限,非常适用于异地备份 何为源端和发起端? 在远程同步过程中,负责发起rs ...

  8. centos 7 源代码 mysql-5.7.2 安装

    CENTOS MYSQL 5.7 下载MySQL 5.7 https://dev.mysql.com/downloads/mysql/5.7.html#downloads cd /usr/local/ ...

  9. blucesun 解决npm报错:Module build failed: TypeError: this.getResolve is not a function

    1.sass-loader的版本过高导致的编译错误,当前最高版本是8.x,需要退回到7.3.1 运行: npm uninstall sass-loader(卸载当前版本) npm install sa ...

  10. 裸磁盘上ext4与xfs在线扩容,非LVM

    虚拟机添加一个20G的硬盘,磁盘为sdb,分区为ext4 格式化一个5Gib的磁盘出来,用dd命令写入4G数据. 一.需求是容量为5G的磁盘,文件系统为ext4的sdb1扩容到10G. 操作步骤为 1 ...