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

直接上代码:

// 获取项目路径
      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. 深入应用C++ 11 C2

    template<typename T> void print(T& t) { cout << "lvalue" << endl; } ...

  2. 关于php性能优化

    php性能优化 1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍. 当然了,这个测试方法需要在十万级以上次执行,效果才明显. 其实静态方 ...

  3. WPF 异步加载窗体

    加载某个界面时,需要获取数据,而数据返回的时间比较长,这个时候可以异步加载界面. 1.在该窗体的加载事件(Load)中编写以下代码: new Thread(p=>{DataBinding();} ...

  4. SQLServer 导入大容量sql文件

    cmd命令行,管理员身份运行 执行以下语句:E:\dbbak\abhs\SmartEnglish_data.sql 为文件路径,AbhsEnglish 为要导入的数据库 sqlcmd -i E:\db ...

  5. 缓存策略:redis缓存之springCache

    最近通过同学,突然知道服务器的缓存有很多猫腻,这里通过网上查询其他人的资料,进行记录: 缓存策略 比较简单的缓存策略: 1.失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放 ...

  6. C#面向对象22 委托事件反射

    1.委托的定义:声明委托类型(返回值和参数,命名空间中):定义委托对象 (把委托想象成函数中的占位符~因为你并不确定调用哪个函数~) using System; using System.Collec ...

  7. ModbusTCP报文详解【二】

    [1]功能码05H [2]功能码06H [3]功能码0FH [4]功能码10H

  8. Linux服务器不关机新增硬盘的方法

    在开机状态下,插入磁盘之后,执行如下命令: ls /sys/class/scsi_host/host0 host1 host2 echo "- - -" > /sys/cla ...

  9. React学习——子组件给父组件传值

    //子组件 var Child = React.createClass({ render: function(){ return ( <div> 请输入邮箱:<input onCha ...

  10. sql分页查询(2005以后的数据库)和access分页查询

    sql分页查询: select * from ( select ROW_NUMBER() over(order by 排序条件) as rowNumber,* from [表名] where 条件 ) ...