You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC字节数组转ZipOutputStream及下载Zip无数据问题求助

解决Spring MVC中字节数组转ZipOutputStream时文件为空的问题

嘿,我来帮你搞定这个问题!你现在遇到的zip文件下载后内容为空的问题,核心原因很明确——你的代码只把ZipEntry的元信息写到了输出流里,完全没复制每个文件的实际内容,所以解压后所有文件都是0字节。

问题根源拆解

你当前的代码逻辑是:从数据库拿到zip字节数组,打开ZipInputStream遍历每个条目,然后直接把原ZipEntry放到ZipOutputStream里就完事了。但zipOutputStream.putNextEntry(ent)只是在输出的zip里创建了一个文件条目,没有把原zip里该文件的内容写进去,自然每个文件都是空的。

修复后的完整代码

我给你调整了代码,用Java的try-with-resources自动管理流(避免手动关流的坑),同时加上了关键的内容复制逻辑:

@RequestMapping(value = ApplicationConstants.ServiceURLS.TRANSLATIONS + "/{resourceId}/attachments", produces = "application/zip")
public void attachments(HttpServletResponse response, @PathVariable("resourceId") Long resourceId) throws IOException {
    TtTranslationCollection tr = translationManagementDAO.getTranslationCollection(resourceId);
    byte[] fileData = tr.getFile();

    // 配置响应头,确保浏览器正确识别zip文件
    response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/zip");
    response.addHeader("Content-Disposition", "attachment; filename=\"attachments.zip\"");

    // try-with-resources会自动关闭所有实现AutoCloseable的流,不用手动调用close()
    try (ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(fileData));
         ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {

        ZipEntry currentEntry;
        // 用缓冲区复制内容,比单字节读取效率高很多
        byte[] buffer = new byte[4096];
        int bytesRead;

        while ((currentEntry = zipStream.getNextEntry()) != null) {
            // 建议创建新的ZipEntry,避免复用原条目可能带来的元数据异常
            ZipEntry newZipEntry = new ZipEntry(currentEntry.getName());
            zipOutputStream.putNextEntry(newZipEntry);

            // 核心步骤:把原zip里的文件内容逐块复制到输出流
            while ((bytesRead = zipStream.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, bytesRead);
            }

            // 关闭当前条目,释放资源
            zipOutputStream.closeEntry();
            zipStream.closeEntry();
        }
    }
}

几个关键改进点

  • 添加内容复制逻辑:用缓冲区循环读取原ZipInputStream的内容,写入ZipOutputStream,这是解决空文件的核心。
  • try-with-resources自动关流:再也不用担心漏关流或者关流顺序错了导致的资源泄漏问题,Java会帮你处理。
  • 创建新的ZipEntry:直接复用原ZipEntry可能会携带一些内部状态,新建条目更稳妥。
  • 明确设置ContentType:显式指定application/zip,确保浏览器能正确识别下载的文件类型。

额外小提示

如果还是有问题,可以先验证数据库里的字节数组是不是有效的zip文件——比如把字节数组写到本地文件,看看能不能正常解压。如果本地也打不开,那可能是存入数据库的时候就出问题了。

内容的提问来源于stack exchange,提问作者Amol Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:24:41