美文网首页
java下载多个文件并打成压缩包

java下载多个文件并打成压缩包

作者: 不要夜空霓虹的繁荣 | 来源:发表于2021-01-11 19:23 被阅读0次
BatMan

先放一张自己喜欢的图片,写着有劲。

——需求:

简单的说下需求,下载多个文件,并按照自定义的需求把文件放在不同文件夹下,并自定义每个文件的名称,

1.数据库

只说重点两个字段。
name,是在页面上显示的文件的名字。
document_url,是此文件存在于你的硬盘上真实的文件名,我是以UUID命名的。


数据库

2.实现类

这一步,是我项目的具体需求,不重要,重要的就是要凑成一个 Map ,也就是我下面的注释部分是主要的。

/**
 *自恋一下
     * 汤氏多文件下载
     * @param ids
     * 组合一个Map<String, Map<String,File>> files
     * 第一层 map 的 key 为最外层的文件夹的名字,
     * 第二层 map 的 key 为这个文件的自定义路径,如:最外层文件夹/文件夹A/文件夹A1/文件.jpg,
     * zip打包后会自动分层。
     * 第二层的 value 是真实存在的文件
     */
    @Override
    public void tangDownloadFiles(List<Long> ids,HttpServletResponse response) {
        List<PlanDocumentRecordsEntity> list = queryFactory.selectFrom(qPlanDocumentRecords).where(qPlanDocumentRecords.deleteStatus.eq(1).and(qPlanDocumentRecords.id.in(ids)).and(qPlanDocumentRecords.catalogOrFile.eq(2))).fetch();
        //存放文件及其文件的父路径
        Map<String,File> fileMap = new HashMap<>();

        for (PlanDocumentRecordsEntity entitie : list){
            String str = entitie.getDocumentUrl();
            String s = "";
            if (entitie.getParentId()!=0){
                String url = this.getParentName(entitie.getParentId(),s)+str;
                File file = new File(upLoadFilePath+str);
                fileMap.put(url,file);
            }
        }
        
        Map<String, Map<String,File>> files = new HashMap<>();
        String planName = "计划";
        if (ids!=null && ids.size()>0){
            //文件件的最外层为此计划的名字
            planName = queryFactory.select(qPlanInfo.name).from(qPlanInfo).leftJoin(qPlanDocumentRecords).on(qPlanDocumentRecords.planId.eq(qPlanInfo.id)).where(qPlanDocumentRecords.id.eq(ids.get(0))).fetchFirst();
        }
        files.put(planName,fileMap);
        //开始打包
        this.zipMultipleFiles(files,response);
    }

其实也是参考的网上别人的写的,但是找不到那个链接了,就不加了
然后我是根据自己的需求所改动了一下。

以下为重要部分。

public void zipMultipleFiles(Map<String, Map<String,File>>files, HttpServletResponse response) {
        //下载的压缩包的名
        String downloadFilename = UUID.randomUUID().toString().replace("-", "");
        System.out.println(downloadFilename);
        ZipOutputStream zos = null;
        InputStream in = null;
        try {
            response.setContentType("application/octet-stream");// 指明response的返回对象是文件流
            response.setHeader("Content-Disposition", "attachment;filename=" + downloadFilename);// 设置在下载框默认显示的文件名
            downloadFilename = URLEncoder.encode(downloadFilename, "UTF-8");
            zos = new ZipOutputStream(response.getOutputStream());
            for (Map.Entry<String, Map<String,File>> entry : files.entrySet()) {
                if (entry.getValue()!=null&&entry.getValue().size()!=0) {
                    //开始循环
                    for (Map.Entry<String,File> fileEntry : entry.getValue().entrySet()){
                        String key = fileEntry.getKey();
                        int i =key.lastIndexOf("/");
                        if (i==-1){
                            i=0;
                        }
                        //此 url 是自己组合的在zip包内的该文件的目录结构,不包括最外层的文件夹,因为最外层的文件夹,是我自己固定好的,也就是下载完的压缩包解压后会有一个固定的最外层的文件夹。(注意并不是文件在硬盘上的实际目录结构,实际的所有的文件都放在了同一个文件夹下了)
                        String url = fileEntry.getKey().substring(0,i);
                        //自定义压缩包内每个文件的名字
                        //这步就是要把文件换成自己想要展示出来的名字,也就是上边数据库中 name 字段。
                        String newFileName = queryFactory.select(qPlanDocumentRecords.name).from(qPlanDocumentRecords).where(qPlanDocumentRecords.documentUrl.eq(fileEntry.getValue().getName())).fetchFirst();
                        //打压缩包
                        //entry.getKey()就是上述所说的最外层的文件夹,也是自己定义的。
                        zos.putNextEntry(new ZipEntry(
                                entry.getKey()+File.separator+ url + File.separator + newFileName));
                        //文件路径放入流
                        in = new FileInputStream(fileEntry.getValue().getPath());
                        byte[] buffer = new byte[1024];
                        int r = 0;
                        while ((r = in.read(buffer)) != -1) {
                            zos.write(buffer, 0, r);
                        }
                        in.close();
                    }
                    zos.flush();
                }
            }
        } catch (Exception e) {
            log.error("zipFiles error!!", e);
        } finally {
            if (zos!=null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    zos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in!=null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

至此你就成功了,上述毕竟是我根据我自己的业务逻辑所写,可能有些代码并用不到,但是最重要的部分我也告诉大家了,所以也可以自己发挥了。

最后以美好的心情结尾

迪丽热巴

相关文章

网友评论

      本文标题:java下载多个文件并打成压缩包

      本文链接:https://www.haomeiwen.com/subject/gfndaktx.html