惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
C
Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
V
Vulnerabilities – Threatpost
博客园 - Franky
A
Arctic Wolf
T
Tenable Blog
P
Privacy & Cybersecurity Law Blog
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
C
CERT Recently Published Vulnerability Notes
Spread Privacy
Spread Privacy
Latest news
Latest news
小众软件
小众软件
Google DeepMind News
Google DeepMind News
IT之家
IT之家
量子位
U
Unit 42
T
Threatpost
I
InfoQ
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
K
Kaspersky official blog
T
Tor Project blog
Scott Helme
Scott Helme
AWS News Blog
AWS News Blog
Hugging Face - Blog
Hugging Face - Blog
PCI Perspectives
PCI Perspectives
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Commits to openclaw:main
Recent Commits to openclaw:main
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
Visual Studio Blog
S
Securelist
L
LINUX DO - 热门话题
Apple Machine Learning Research
Apple Machine Learning Research
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
D
DataBreaches.Net

博客园 - 子墨老师

基于Hutool的poi导出excel表格【升级更新】 如何设置wps单元格下拉选项设置 Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException: Encryption raised an exception ZoomIt的使用与快捷键 springboot项目中使用Java 8的日期时间API 基于springboot系统,如何跟踪会话过期,浏览器会话标识是否收到正常响应,存储,并在后续请求保持携带 SpringBoot+MyBatis实现数据库字段加密 Vue2中能否实现输入中文自动转化为拼音, 且不带音调 Excel导出问题:accessExternalStylesheet 解构赋值+扩展运算符在数组和对象上的应用例子 收藏一下JDK下载地址 介绍几个axios接口请求顺序的问题 vue cli的介绍 Failed to start nginx.service: Unit nginx.service not found. 如何能成功在centos7下安装nodejs18+以上版本 centos7下卸载nodejs源码包 基于ConcurrentMap锁机制的NFS文件合并方案 基于ConcurrentMap锁机制的NFS分片上传方案 如何将已经存在的本地项目源码关联到远程git仓库中 gitee如何使用 centos7安装php+wordpress
如何实现文件批量重命名后再进行批量打包下载
子墨老师 · 2025-10-20 · via 博客园 - 子墨老师

在项目中会遇到一些批量下载打包的简单功能,今天我们给大家分享一个:批量打包下载,且对打包的文件进行批量重名

1.表结构

字段名 备注
tutorial_id 教材ID
turtorial_origin_name 源文件名
turtorial_upload_name 存储文件名
turtorial_upload_path 存储路径
turtorial_sort 教材排序

2.功能描述

(1)库表存储的文件以“turtorial_upload_name”为标准,文件名称随机生成的uuid

(2)当批量下载文件,其打包文件名字根据“turtorial_upload_name”命名

问题:如果我们需要在进行打包下载之前修改文件名称为“源文件名”,程序应该如何实现

3.初期代码实现

(1)依赖包:hutool

(2)工具类:cn.hutool.core.util.ZipUtil

(3)实现基本思路:

  • 获取多个教材的路径,封装到File中
  • 设置文件压缩的路径,此路径为临时下载路径
  • 创建ZipUtil对象,封装多个教材的File对象
  • IO流传输
  • 删除临时

初期代码参考

    public void donwloadTutorial(String fileName, String paramJson, HttpServletResponse response) throws IOException {
        // 返回json字符串为集合,通过TypeReference进行类型转换
        List<Map<String,String>> param = JsonFactory.json2bean(paramJson, new JsonFactory.TypeReference<List<Map<String,String>>>());

        List<File> fileList = new ArrayList<>();
        // 获取教材的路径
        for (Map<String, String> map : param) {
            String tutorialUploadPath = map.get("tutorialUploadPath");
            String filePath = downloadPath + tutorialUploadPath;
            fileList.add(FileUtil.file(filePath));
        }

        // 文件压缩,并保存到临时路径
        File zipFile = new File(downloadPath + "achive.zip");
        ZipUtil.zip(zipFile, false, fileList.toArray(new File[fileList.size()]));
        InputStream is = new FileInputStream(zipFile);
        ResponseExportUtil.exportFileWithStream(response, is, fileName);
        is.close();

        // 删除临时文件
        FileUtil.del(zipFile);
    }

4.优化代码,完成文件重名再打包下载

基本思路:

  • 创建临时目录,存放重命名后的文件
  • 获取教材的路径
  • 复制并覆盖同名文件
  • 文件压缩,并保存到临时路径
  • 发送压缩文件
  • 删除临时文件

优化后代码参考

    public void donwloadTutorial(String fileName, String paramJson, HttpServletResponse response) throws IOException {
        // 返回json字符串为集合,通过TypeReference进行类型转换
        List<Map<String,String>> param = JsonFactory.json2bean(paramJson, new JsonFactory.TypeReference<List<Map<String,String>>>());

        // 创建临时目录存放重命名后的文件
        File tempDir = FileUtil.mkdir(downloadPath + "/temp/" + "tutorial_download_" + System.currentTimeMillis());
        List<File> renamedFiles = new ArrayList<>();
        File zipFile = new File(downloadPath + "achive.zip"); // 压缩文件临时存储名称
        try {
            // 获取教材的路径
            for (Map<String, String> map : param) {
                String tutorialUploadPath = map.get("tutorialUploadPath"); // 教材上传路径
                String tutroialOriginName = map.get("tutorialOriginName"); // 教材原始名称
                // 验证原始文件名非空且合法
                if (StrUtil.isBlank(tutroialOriginName)) {
                    throw new IllegalArgumentException("原始文件名不能为空");
                }
                tutroialOriginName = FileUtil.cleanInvalid(tutroialOriginName); // 清理非法字符

                String filePath = downloadPath + tutorialUploadPath; // 源文件的路径, 例如, /data/upload/course_content/tutorial/pdf/2023-05-05/1.pdf
                File sourceFile = FileUtil.file(filePath); // 源文件,存储在数据库上的真实路径
                if (!sourceFile.exists()) {
                    throw new FileNotFoundException("文件不存在: " + sourceFile.getPath());
                }

                // 在临时目录创建重命名后的文件
                File renamedFile = FileUtil.file(tempDir, tutroialOriginName); // 在临时目录创建重命名后的文件
                FileUtil.copy(sourceFile, renamedFile, true); // 复制并覆盖同名文件
                renamedFiles.add(renamedFile);
            }

            // 文件压缩,并保存到临时路径
            ZipUtil.zip(zipFile, false, renamedFiles.toArray(new File[renamedFiles.size()]));

            // 发送压缩文件
            try (InputStream is = new FileInputStream(zipFile)) {
                ResponseExportUtil.exportFileWithStream(response, is, fileName);
            }
        } finally {
            // 删除临时文件
            FileUtil.del(tempDir);
            FileUtil.del(zipFile);
        }
    }