将文件数据分类,存放不同目录,压缩后下载

准备数据

构建测试实体



@Data
@Builder
public class ZipDownEntity {

    private String time;
    private String name;
    private File file;
}

构建出数据

 private List<ZipDownEntity> buildData() {
        List<ZipDownEntity> list = new ArrayList<>();
        try {
            ZipDownEntity no1_1 = ZipDownEntity.builder().time("20240801").name("文件一").file(File.createTempFile("1-1.txt",null)).build();
            ZipDownEntity no1_2 = ZipDownEntity.builder().time("20240801").name("文件一").file(File.createTempFile("1-2.txt",null)).build();
            ZipDownEntity no1_3 = ZipDownEntity.builder().time("20240801").name("文件二").file(File.createTempFile("2-1.txt",null)).build();
            ZipDownEntity no2_1 = ZipDownEntity.builder().time("20240802").name("文件一").file(File.createTempFile("1-1.txt",null)).build();
            ZipDownEntity no2_2 = ZipDownEntity.builder().time("20240802").name("文件一").file(File.createTempFile("1-2.txt",null)).build();
            ZipDownEntity no2_3 = ZipDownEntity.builder().time("20240802").name("文件二").file(File.createTempFile("2-1.txt",null)).build();
            ZipDownEntity no3_1 = ZipDownEntity.builder().time("20240803").name("文件一").file(File.createTempFile("1-1.txt",null)).build();
            ZipDownEntity no3_2 = ZipDownEntity.builder().time("20240803").name("文件一").file(File.createTempFile("1-2.txt",null)).build();
            ZipDownEntity no3_3 = ZipDownEntity.builder().time("20240803").name("文件二").file(File.createTempFile("2-1.txt",null)).build();
            list.add(no1_1);
            list.add(no1_2);
            list.add(no1_3);
            list.add(no2_1);
            list.add(no2_2);
            list.add(no2_3);
            list.add(no3_1);
            list.add(no3_2);
            list.add(no3_3);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return list;
    }
}

获取HttpServletResponse

  private HttpServletResponse buildHttpServletResponse() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes1 = (ServletRequestAttributes) attributes;
        return attributes1.getResponse();
    }

下载

    private void downFile(HttpServletResponse response, File file) {

        try (   BufferedInputStream fis  =new BufferedInputStream(Files.newInputStream(file.toPath()));
                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());){
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            // 清空response
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");

            // 对文件名进行 URL 编码
            response.setCharacterEncoding(String.valueOf(StandardCharsets.UTF_8));
            String fileName = URLEncoder.encode(file.getName(), String.valueOf(StandardCharsets.UTF_8));
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            toClient.write(buffer);
            toClient.flush();
        } catch (Exception e) {
            log.error("下载zip压缩包过程发生异常:", e);
        }

第一种方式:使用ZipOutputStream

@Service
@Slf4j
public class ZipDownServiceImpl implements ZipDownService {
    @Override
    public void down() {
        //数据构建
        List<ZipDownEntity> zipDownEntitieList = this.buildData();
        //按照日期分包--日期后在按照名称
        if (CollectionUtils.isEmpty(zipDownEntitieList)){
            return;
        }
        Map<String,Map<String,List<ZipDownEntity>>> map = new HashMap<>();
        Map<String, List<ZipDownEntity>> timeMap = zipDownEntitieList.stream().collect(Collectors.groupingBy(ZipDownEntity::getTime));
        timeMap.forEach((key, value)->{
            Map<String, List<ZipDownEntity>> nameMapValue = value.stream().collect(Collectors.groupingBy(ZipDownEntity::getName));
            map.put(key,nameMapValue);

        });
        this.doDownload(map);
    }

    private void doDownload(Map<String, Map<String, List<ZipDownEntity>>> map) {
        //构建HttpServletResponse
        HttpServletResponse response = this.buildHttpServletResponse();
        File file = FileUtil.newFile("下载.zip");;
        try (FileOutputStream fos = new FileOutputStream(file);
             //CheckedOutputStream  csum = new CheckedOutputStream(fos, new Adler32());
             ZipOutputStream zos = new ZipOutputStream(fos);){
            //获取文件和文件存储路径
            Set<Map.Entry<String, Map<String, List<ZipDownEntity>>>> entries = map.entrySet();
            for (Map.Entry<String, Map<String, List<ZipDownEntity>>> entry : entries) {
                //名称路径
                for (Map.Entry<String, List<ZipDownEntity>> nameEntity : entry.getValue().entrySet()) {
                    for (ZipDownEntity data : nameEntity.getValue()) {
                        //在压缩包中全路径
                        String folder = entry.getKey() + File.separator  //日期
                                + nameEntity.getKey() + File.separator   //名称
                                + data.getFile().getName();              //文件名
                        zos.write(FileUtil.readBytes(data.getFile()));
                        zos.putNextEntry(new ZipEntry(folder));
                        zos.closeEntry();
                    }
                }
            }
            //下载压缩包
            this.downFile(response,file);
        } catch (IOException e){
            throw new RuntimeException(e);
        }finally {
            file.delete();
        }
    }

  

   
   

第二种方式:使用Hutool得ZIP

@Service
@Slf4j
public class ZipDownServiceImpl implements ZipDownService {
    @Override
    public void down() {
        //数据构建
        List<ZipDownEntity> zipDownEntitieList = this.buildData();
        //按照日期分包--日期后在按照名称
        if (CollectionUtils.isEmpty(zipDownEntitieList)){
            return;
        }
        Map<String,Map<String,List<ZipDownEntity>>> map = new HashMap<>();
        Map<String, List<ZipDownEntity>> timeMap = zipDownEntitieList.stream().collect(Collectors.groupingBy(ZipDownEntity::getTime));
        timeMap.forEach((key, value)->{
            Map<String, List<ZipDownEntity>> nameMapValue = value.stream().collect(Collectors.groupingBy(ZipDownEntity::getName));
            map.put(key,nameMapValue);

        });
        this.doDownload(map);
    }

    private void doDownload(Map<String, Map<String, List<ZipDownEntity>>> map) {
        //构建HttpServletResponse
        HttpServletResponse response = this.buildHttpServletResponse();
        File file = FileUtil.newFile("下载.zip");;
        String dir = System.getProperty("user.dir") + File.separator + "myFolder.zip";
        //FileUtil.mkdir(dir);
        String currentFolder = System.getProperty("user.dir")+File.separator+"myFolder";
        List<File> fileList = new ArrayList<>();
        try {
            //获取文件和文件存储路径
            Set<Map.Entry<String, Map<String, List<ZipDownEntity>>>> entries = map.entrySet();
            for (Map.Entry<String, Map<String, List<ZipDownEntity>>> entry : entries) {
                //名称路径
                for (Map.Entry<String, List<ZipDownEntity>> nameEntity : entry.getValue().entrySet()) {
                    for (ZipDownEntity data : nameEntity.getValue()) {
                        //在压缩包中全路径
                        String folder = currentFolder + File.separator
                                + entry.getKey() + File.separator  //日期
                                + nameEntity.getKey() + File.separator + data.getFile().getName();//文件名
                        //复制到目录
                        FileUtil.copy(data.getFile(), new File(folder), true);
                       
                    }
                }
            }
            ZipUtil.zip(currentFolder,dir);
            this.downFile(response,new File(dir));
        } catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            //删除临时目录
            FileUtil.del(currentFolder);
            FileUtil.del(dir);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值