Java实现将文件或者文件夹压缩zip,响应放回浏览器下载

963 阅读1分钟

Java实现将文件或者文件夹压缩成zip ,总是报错:throw new ZipException(“no current ZIP entry”)

问题出现的环境背景及自己尝试过哪些方法

1、断点程序跟踪调试,执行到ZipOutputStream 类 write 方法325行 current对象始终为空
2、在本地main方法测试是可以正常打包zip
3、响应头已设置

相关代码

 /**
     * 多个文件打包压缩下载
     *
     * @param response
     */
    @GetMapping(value = "/download/zip")
    @ApiOperation(value = "文件压缩下载", notes = "文件压缩下载")
    public void batchDownload(@RequestParam("id") Integer id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHmmss"));
        response.reset();
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName,"UTF-8")
                + CommonConstants.ZIP_NAME_SUFFIX);

        EstateImageText estateImageText = estateImageTextService.getById(id);
        long start = System.currentTimeMillis();
        try {
            if (ObjectUtil.isNotEmpty(estateImageText)) {
                String imageUrl = estateImageText.getImageUrl();
                if (StrUtil.isNotEmpty(imageUrl)) {
                    // 文件路径
                    List<String> fileUrlList = new ArrayList<>(Arrays.asList(imageUrl.split(EstateConstants.SEPARATOR_CHAR)));
                    ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());

                    List<File> listFiles = Lists.newArrayList();

                    for (int i = 0; i < fileUrlList.size(); i++) {
                        String strDir = fileUrlList.get(i);
                        File sourceFile = new File(FileUtil.normalize(strDir));
                        listFiles.add(sourceFile);
                    }
                    // 文件压缩
                    ZipUtils.toZip(listFiles,zipOutputStream );
                }
                long end = System.currentTimeMillis();
                log.info("压缩完成,耗时:" + (end - start) + "ms");
            }
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("------------文件压缩打包错误------------------", e.getMessage());
        }
    }

=======================ZipUtils 工具类=========================
/**
     * 压缩方法
     *
     * @param srcFiles 需要压缩的文件列表
     * @param out      压缩文件输出流
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(List<File> srcFiles, OutputStream out) {
        log.info("正在压缩中...");
        long start = System.currentTimeMillis();
        ZipOutputStream zip = null;
        FileInputStream in = null;
        try {

            zip = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] bufBytes = new byte[BUFFER_SIZE];
                // 将文件夹放入zip中
                zip.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                in = new FileInputStream(srcFile);
                while ((len = in.read(bufBytes)) != -1) {
                    zip.write(bufBytes, 0, len);
                }
                // 压缩完成后,关闭压缩流
                zip.closeEntry();
                in.close();
            }

            long end = System.currentTimeMillis();
            log.info("压缩完成,耗时:" + (end - start) + " ms");

        } catch (FileNotFoundException e) {
            log.error("系统找不到指定的文件", e.getMessage());
            throw new RuntimeException("系统找不到指定的文件", e);
        } catch (Exception e) {
            log.error("-------------ZipUtils-------------", e.getMessage());
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (null != zip) {
                try {
                    zip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

你期待的结果是什么?实际看到的错误信息又是什么?

1、预期结果期望将多个不同格式文件打包成一个zip 包,返回到浏览器下载,并正常解压文件内部不能丢失!
2、实际结果报错:throw new ZipException(“no current ZIP entry”)
3、暂不考虑多层级文件目录结构