zipOutputStream压缩后用RAR解压出现“不可预料的压缩文件末端”错误

最近需要压缩做一个多重压缩文件的需求,出现了一个不可预料的压缩文件末端错误

代码:

 public void getBatchDocDownload(HttpServletRequest request, HttpServletResponse response,DownloadDocReq downloadDocReq) throws Exception {
        List<GroupReq> groupReqList = downloadDocReq.getGroupReqs();
        if (CollectionUtils.isNotEmpty(groupReqList)) {
            String fileName = "附件批量下载.zip";
            response.setContentType("application/zip");
            String agent = request.getHeader("USER-AGENT");
            String downloadFileName = "";
            String firefox = "firefox";
            if (agent != null && agent.toLowerCase().indexOf(firefox) > NumberUtils.INTEGER_ZERO) {
                downloadFileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
            } else {
                downloadFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("%2B", "\\+")
                        .replaceAll("%28", "\\(")
                        .replaceAll("%29", "\\)")
                        .replaceAll("%3B", ";")
                        .replaceAll("%40", "@")
                        .replaceAll("%23", "\\#")
                        .replaceAll("%26", "\\&")
                        .replaceAll("\\+", "%20");

            }
            response.setHeader("Content-Disposition", "attachment; filename=" + downloadFileName);
            // 用于将数据压缩成Zip文件格式
            List<Long> docIdList = Lists.newArrayList();
            groupReqList.forEach(
                    e->{
                        List<DocDownloadReq> docDownloadReqs = e.getDocDownloadReqs();
                        if(CollectionUtils.isNotEmpty(docDownloadReqs)) {
                            //文件ids
                            List<Long> docIds = docDownloadReqs.stream().map(DocDownloadReq::getDocId).collect(Collectors.toList());
                            if(CollectionUtils.isNotEmpty(docIds)){
                                docIdList.addAll(docIds);
                            }
                        }
                    });
            List<DocEntity> docEntityList = Lists.newArrayList();
            if(CollectionUtils.isNotEmpty(docIdList)){
                docEntityList = docDao.selectBatchIds(docIdList);
            }
            try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
                for (GroupReq groupReq : groupReqList) {
                    List<DocDownloadReq> docDownloadReqs = groupReq.getDocDownloadReqs();
                    if(CollectionUtils.isNotEmpty(docDownloadReqs)){
                        // 用于将数据压缩成Zip文件格式并放入到字节数组输出流
                        try (ByteArrayOutputStream allBos = new ByteArrayOutputStream(); ZipOutputStream fileZip = new ZipOutputStream(allBos)) {
                            for (DocDownloadReq docDownloadReq : docDownloadReqs) {
                                if(CollectionUtils.isNotEmpty(docEntityList)){
                                    //根据docId获取对应的pathKey
                                    DocEntity docEntity = docEntityList.stream().filter(e->e.getId().equals(docDownloadReq.getDocId())).findAny().orElse(null);
                                    if(docEntity != null){
                                        // 获取Object,返回结果为OSSObject对象
                                        byte[] data = baseDocStorageHandler.getBytes(docEntity.getPathKey());
                                        //将byte字节流放入fileZip中,并且设置文件名称
                                        fileZip.putNextEntry(new ZipEntry(docDownloadReq.getDocName()));
                                        fileZip.write(data);
                                        fileZip.flush();
                                        //关闭
                                        fileZip.closeEntry();
                                    }
                                }
                            }
                            fileZip.finish();
                            zos.putNextEntry(new ZipEntry(groupReq.getGroupName() + ".zip"));
                            zos.write(allBos.toByteArray());
                            zos.flush();
                            zos.closeEntry();
                        } catch (Exception exception) {
                            log.error(exception.getMessage());
                        }
                    }
                }
                zos.finish();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }

主要是要在zos.closeEntry();之前进行刷新缓存 zos.flush();,在关闭之后进行 zos.finish();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值