【java打包下载zip树形结构】打包的时候在zip里创建文件夹自定义路径

在这里插入图片描述

1、测试类

import lombok.Data;

@Data
public class ZipVo {
    //文件路径:开始和结束都要/斜杠,生成属性文件夹
    private String pathName;
    //文件数据
    private String data;
    private String type;
    //后缀suffix
    private String suffix;
}

2、控制器

import com.ekkcole.utils.Func;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 树形层级下载打包下载zip
 */
@RestController
public class TestZip {
    /**
     * 树形层级下载打包下载zip
     * 参数自定义
     */
    @GetMapping("/generateFileGroupDownZip")
    public void generateFileGroupDownZip(HttpServletResponse response) {
        //TODO 设置测试数据
        List<ZipVo> zipVoList = new ArrayList<>();
        ZipVo bean = new ZipVo();
        bean.setData("http://localhost:8999/machine/upload/image/20230922/29909950475117.docx");
//        bean.setData("C:\\Users\\Administrator\\Desktop\\zhuomian\\测试图\\1.jpg");
        bean.setPathName("/常州/武进/");
        bean.setType(".jpg");
        zipVoList.add(bean);
        ZipVo bean1 = new ZipVo();
        bean1.setData("http://localhost:8999/machine/upload/image/20230922/30035456012377.zip");
//        bean1.setData("C:\\Users\\Administrator\\Desktop\\zhuomian\\测试图\\1.jpg");
        bean1.setPathName("/常州/武进/湖塘/");
        bean1.setType(".jpg");
        zipVoList.add(bean1);
        ZipVo bean2 = new ZipVo();
        bean2.setData("http://localhost:8999/machine/upload/image/20230922/30895400564085.docx");
//        bean2.setData("C:\\Users\\Administrator\\Desktop\\zhuomian\\测试图\\1.jpg");
        bean2.setPathName("/徐州/睢宁/庆安/");
        bean2.setType(".jpg");
        zipVoList.add(bean2);

        //设置最终输出zip文件名,后缀记得加
        String zipFileName = "测试" + ".zip";
        // 定义zip输出流
        ZipOutputStream zipStream = null;
        BufferedInputStream bufferStream = null;
        File zipFile = new File(zipFileName);
        try {
            //构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            // 通过lambda表达式分组
            Map<String, List<ZipVo>> collect = zipVoList.stream().collect(Collectors.groupingBy(ZipVo::getPathName));
            // 遍历分组
            for (Map.Entry<String, List<ZipVo>> zipMap : collect.entrySet()) {
                // 获取分组键
                String key = zipMap.getKey();
                // 获取分组值
                List<ZipVo> zipMapValueList = zipMap.getValue();
                // 如果分组值不为空则遍历数组
                if (zipMapValueList.size() > 0) {
                    // 遍历分组值列表
                    for (ZipVo zipVo : zipMapValueList) {
                        // 获取文件的数据
                        String attachUrl = zipVo.getData();
                        // 获取后缀
                        String suffix = zipVo.getType();
                        //TODO 以下方式来自上面测类data里面的数据,根据自己填写的类型使用对应的
                        //方式一:--------------------根据base64获取文件InputStream流---------------
//                        BASE64Decoder decoder = new BASE64Decoder();
                        // Base64解码,对字节数组字符串进行Base64解码并生成文件
//                        byte[] byt = decoder.decodeBuffer(attachUrl);
//                        for (int a = 0, len = byt.length; a < len; ++a) {
//                            // 调整异常数据
//                            if (byt[a] < 0) {
//                                byt[a] += 256;
//                            }
//                        }
//                        InputStream input = new ByteArrayInputStream(byt);


                        //方式二:------------------------根据url获取------------------
                        InputStream input = getInputStream(attachUrl);


                        //方式三:-----------------------根据指定路径获取文件----------------------
//                        File file = new File(attachUrl);
//                        InputStream input=new FileInputStream(file);
                        /**
                         * 文件和文件夹命名
                         * 文件:名称 + 后缀  
                         * 文件夹:"\\" + 文件名 + "\\"
                         * 组合使用: 文件夹 + 文件
                         */
                        ZipEntry zipEntry = new ZipEntry("\\" + key + "\\" + System.currentTimeMillis() + suffix);
                        zipStream.putNextEntry(zipEntry);
                        bufferStream = new BufferedInputStream(input, 1024 * 10);
                        int read = 0;
                        byte[] buf = new byte[1024 * 10];
                        while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
                            zipStream.write(buf, 0, read);
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (null != bufferStream) {
                    bufferStream.close();
                }
                if (null != zipStream) {
                    zipStream.flush();
                    zipStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //判断系统压缩文件是否存在:true-把该压缩文件通过流输出给客户端后删除该压缩文件  false-未处理
        if (zipFile.exists()) {
            // 调用下载方法
            groupDownZip(response, zipFileName);
            zipFile.delete();
        }
    }

    /**
     * @param response http相应
     * @param filename 文件名
     */
    private void groupDownZip(HttpServletResponse response, String filename) {
        if (filename != null) {
            FileInputStream inputStream = null;
            BufferedInputStream bufferedInputStream = null;
            OutputStream outputStream = null;
            try {
                File file = new File(filename);
                if (file.exists()) {
                    //设置Headers
                    response.setHeader("Content-Type", "application/octet-stream");
                    //设置下载的文件的名称-该方式已解决中文乱码问题
                    response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO-8859-1"));

                    inputStream = new FileInputStream(file);
                    bufferedInputStream = new BufferedInputStream(inputStream);
                    outputStream = response.getOutputStream();
                    byte[] buffer = new byte[1024];
                    int lenth = 0;
                    while ((lenth = bufferedInputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, lenth);
                    }
                } else {
                    String error = Base64Util.encode("文件内容为空");
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (bufferedInputStream != null) {
                        bufferedInputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.flush();
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private InputStream getInputStream(String attachUrl) {
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;
        try {
            if (Func.isNotEmpty(attachUrl)) {
                //处理中文名
                String[] args = attachUrl.split("/");
                String name1 = args[args.length - 1];
                String name2 = java.net.URLEncoder.encode(name1, "utf-8");
                String newUrl = attachUrl.replace(name1, name2);
                url = new URL(newUrl);
                httpUrl = (HttpURLConnection) url.openConnection();
                // 设置超时时间,避免连接超时影响接口速度
                httpUrl.setConnectTimeout(900);
                httpUrl.setReadTimeout(900);
                httpUrl.connect();
                is = httpUrl.getInputStream();
                return is;
            }
        } catch (Exception e) {

        }
        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值