You need to enable JavaScript to run this app. 如何在Spring Boot中通过REST API实现目录压缩功能?
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot中通过REST API实现目录压缩功能?

错误原因

你代码报错的核心原因是FileInputStream仅支持读取普通文件,无法直接读取目录对象。你传入的C:\\Pavan\\zipfolder是目录路径,直接构造FileInputStream就会触发FileNotFoundException。


可运行的Spring Boot实现代码

依赖说明(可选)

如果使用Apache Commons IO做流复制,先在pom.xml引入依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

不需要额外依赖的话可以自己实现流复制逻辑,下方代码会标注替换位置。

完整Controller代码

import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
public class ZipController {

    // 替换为你要压缩的根目录路径
    private static final String ROOT_ZIP_PATH = "C:\\Pavan\\zipfolder";

    @RequestMapping(value = "/zip", produces = "application/zip")
    public void zipDirectory(HttpServletResponse response) throws IOException {
        response.setStatus(HttpServletResponse.SC_OK);
        response.addHeader("Content-Disposition", "attachment; filename=\"compressedfile.zip\"");
        // try-with-resources会自动关闭流,无需手动处理资源释放
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
            File rootFile = new File(ROOT_ZIP_PATH);
            // 递归添加目录下所有文件到压缩包
            addFileToZip(rootFile, rootFile.getName(), zipOutputStream);
        }
    }

    /**
     * 递归添加文件/目录到压缩包
     * @param file 当前处理的文件/目录对象
     * @param entryName 压缩包内的路径,用于保留原目录层级
     * @param zipOutputStream 压缩输出流
     * @throws IOException IO异常
     */
    private void addFileToZip(File file, String entryName, ZipOutputStream zipOutputStream) throws IOException {
        if (file.isDirectory()) {
            // 处理目录:末尾加/标识为目录,空目录也会正常写入压缩包
            String dirEntryName = entryName.endsWith("/") ? entryName : entryName + "/";
            zipOutputStream.putNextEntry(new ZipEntry(dirEntryName));
            zipOutputStream.closeEntry();
            // 遍历子文件递归处理
            File[] childFiles = file.listFiles();
            if (childFiles != null) {
                for (File childFile : childFiles) {
                    addFileToZip(childFile, dirEntryName + childFile.getName(), zipOutputStream);
                }
            }
            return;
        }
        // 处理普通文件
        zipOutputStream.putNextEntry(new ZipEntry(entryName));
        try (FileInputStream fis = new FileInputStream(file)) {
            // 不用commons-io的话,把下面这行替换为注释里的代码即可
            IOUtils.copy(fis, zipOutputStream);
            /* 无依赖的流复制代码
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                zipOutputStream.write(buffer, 0, len);
            }
            */
        }
        zipOutputStream.closeEntry();
    }
}

注意事项

  • 代码会完整保留原目录的层级结构,压缩包内的文件路径和本地目录结构完全一致
  • 支持空目录、多层嵌套目录的压缩
  • 部署到Linux环境时只需要把ROOT_ZIP_PATH改为对应Linux路径即可,无需修改其他逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 00:30:02