SpringBoot + zip4j 实现多文件批量下载并压缩

2023-05-16

重点功能代码:

@Async("threadPoolNeo4jTaskExecutor")
	public void batchDownload(Long engSid, UserDownload entity) {
		// 查询指定案卷信息
		File rootDir = null;
		File archDir = null;
		String tempDirStr = null;
		ArchInfo archInfo = archInfoService.selectByPrimaryKey(entity.getArchSid());
		if (archInfo != null) {
			// 电子文件打包中
			entity.setSid(engSid);
			entity.setDownloadState("2");
			userDownloadService.updateByPrimaryKeySelective(entity);

			String rootDirStr = this.rootPath();
			tempDirStr = String.valueOf(System.currentTimeMillis());// 临时存放目录
			rootDir = new File(rootDirStr, tempDirStr);
			if (!rootDir.exists()) {
				rootDir.mkdir();
			}
			archDir = new File(rootDir, archInfo.getArchTitle());
			if (!archDir.exists()) {
				archDir.mkdirs();
			}

			// 查询指定案卷涉及电子文件
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("archSid", archInfo.getSid());
			List<FileInfo> fileInfos = fileInfoService.findByParams(param);
			if (CollectionUtils.isNotEmpty(fileInfos)) {
				for (FileInfo item : fileInfos) {
					// 获取文件根路径
					String fileDir = transPath(item.getPdfPath() != null ? item.getPdfPath() : "");
					if (fileDir != null || fileDir.length() > 0) {
						File file = new File(fileDir + item.getPdfFilename());
						// 判断文件是否存在
						if (file.exists() && archDir.exists()) {
							// 文件拷贝
							try {
								FileUtils.copyFile(file, new File(archDir, item.getFileTitle() + ".pdf"));
							} catch (Exception e) {
								log.error("export efile task, copy pdf file error : ", e);
							}
						}
					}
				}
				try {
					Zip4jUtil.zip(archDir.getAbsolutePath(),
							rootDir.getAbsolutePath() + File.separator + archInfo.getArchTitle() + ".zip", "");
				} finally {
					// 电子文件打包下载完成
					entity.setSid(engSid);
					entity.setDownloadState("3");
					entity.setDownloadAddress(
							rootDir.getAbsolutePath() + File.separator + archInfo.getArchTitle() + ".zip");
					userDownloadService.updateByPrimaryKeySelective(entity);
				}
			}
		}
	}

Zip4jUtil 工具类源码:


import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

/** 
 * ZIP压缩文件操作工具类 
 * 支持密码 
 * 依赖zip4j开源项目(http://www.lingala.net/zip4j/) 
 * 版本1.3.1 
 */  
public class Zip4jUtil {  
      
    /** 
     * 使用给定密码解压指定的ZIP压缩文件到指定目录 
     * <p> 
     * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出 
     * @param zip 指定的ZIP压缩文件 
     * @param dest 解压目录 
     * @param passwd ZIP文件的密码 
     * @return 解压后文件数组 
     * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 
     */  
    public static File [] unzip(String zip, String dest, String passwd) throws ZipException {  
        File zipFile = new File(zip);  
        return unzip(zipFile, dest, passwd);  
    }  
      
    /** 
     * 使用给定密码解压指定的ZIP压缩文件到当前目录 
     * @param zip 指定的ZIP压缩文件 
     * @param passwd ZIP文件的密码 
     * @return  解压后文件数组 
     * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 
     */  
    public static File [] unzip(String zip, String passwd) throws ZipException {  
        File zipFile = new File(zip);  
        File parentDir = zipFile.getParentFile();  
        return unzip(zipFile, parentDir.getAbsolutePath(), passwd);  
    }  
      
    /** 
     * 使用给定密码解压指定的ZIP压缩文件到指定目录 
     * <p> 
     * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出 
     * @param zip 指定的ZIP压缩文件 
     * @param dest 解压目录 
     * @param passwd ZIP文件的密码 
     * @return  解压后文件数组 
     * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 
     */  
    @SuppressWarnings("unchecked")
	public static File [] unzip(File zipFile, String dest, String passwd) throws ZipException {  
        ZipFile zFile = new ZipFile(zipFile);
//        zFile.setFileNameCharset(ApplicationPropertiesHolder.getProperty("zip4j.charset", "GBK"));
        zFile.setFileNameCharset("GBK");
        if (!zFile.isValidZipFile()) {  
            throw new ZipException("压缩文件不合法,可能被损坏.");  
        }  
        File destDir = new File(dest);  
        if (destDir.isDirectory() && !destDir.exists()) {  
            destDir.mkdir();  
        }  
        if (zFile.isEncrypted()) {
            zFile.setPassword(passwd.toCharArray());  
        }  
        zFile.extractAll(dest);  
          
        List<FileHeader> headerList = zFile.getFileHeaders();  
        List<File> extractedFileList = new ArrayList<File>();  
        for(FileHeader fileHeader : headerList) {  
            if (!fileHeader.isDirectory()) {  
                extractedFileList.add(new File(destDir,fileHeader.getFileName()));  
            }  
        }  
        File [] extractedFiles = new File[extractedFileList.size()];  
        extractedFileList.toArray(extractedFiles);  
        return extractedFiles;  
    }  
      
    /** 
     * 压缩指定文件到当前文件夹 
     * @param src 要压缩的指定文件 
     * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. 
     */  
    public static String zip(String src) {  
        return zip(src,null);  
    }  
      
    /** 
     * 使用给定密码压缩指定文件或文件夹到当前目录 
     * @param src 要压缩的文件 
     * @param passwd 压缩使用的密码 
     * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. 
     */  
    public static String zip(String src, String passwd) {  
        return zip(src, null, passwd);  
    }  
      
    /** 
     * 使用给定密码压缩指定文件或文件夹到当前目录 
     * @param src 要压缩的文件 
     * @param dest 压缩文件存放路径 
     * @param passwd 压缩使用的密码 
     * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. 
     */  
    public static String zip(String src, String dest, String passwd) {  
        return zip(src, dest, true, passwd);  
    }  
      
    /** 
     * 使用给定密码压缩指定文件或文件夹到指定位置. 
     * <p> 
     * dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者"".<br /> 
     * 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀;<br /> 
     * 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名. 
     * @param src 要压缩的文件或文件夹路径 
     * @param dest 压缩文件存放路径 
     * @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效.<br /> 
     * 如果为false,将直接压缩目录下文件到压缩文件. 
     * @param passwd 压缩使用的密码 
     * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. 
     */  
    public static String zip(String src, String dest, boolean isCreateDir, String passwd) {  
        File srcFile = new File(src);  
        dest = buildDestinationZipFilePath(srcFile, dest);  
        ZipParameters parameters = new ZipParameters();  
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);           // 压缩方式  
        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);    // 压缩级别  
        if (!StringUtils.isBlank(passwd)) {
            parameters.setEncryptFiles(true);  
            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 加密方式  
            parameters.setPassword(passwd.toCharArray());  
        }  
        try {  
            ZipFile zipFile = new ZipFile(dest);  
            if (srcFile.isDirectory()) {  
                // 如果不创建目录的话,将直接把给定目录下的文件压缩到压缩文件,即没有目录结构  
                if (!isCreateDir) {  
                    File [] subFiles = srcFile.listFiles();  
                    ArrayList<File> temp = new ArrayList<File>();  
                    Collections.addAll(temp, subFiles);  
                    zipFile.addFiles(temp, parameters);  
                    return dest;  
                }  
                zipFile.addFolder(srcFile, parameters);  
            } else {  
                zipFile.addFile(srcFile, parameters);  
            }  
            return dest;  
        } catch (ZipException e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
      
    /** 
     * 构建压缩文件存放路径,如果不存在将会创建 
     * 传入的可能是文件名或者目录,也可能不传,此方法用以转换最终压缩文件的存放路径 
     * @param srcFile 源文件 
     * @param destParam 压缩目标路径 
     * @return 正确的压缩文件存放路径 
     */  
    private static String buildDestinationZipFilePath(File srcFile,String destParam) {  
        if (StringUtils.isBlank(destParam)) {  
            if (srcFile.isDirectory()) {  
                destParam = srcFile.getParent() + File.separator + srcFile.getName() + ".zip";  
            } else {  
                String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));  
                destParam = srcFile.getParent() + File.separator + fileName + ".zip";  
            }  
        } else {  
            createDestDirectoryIfNecessary(destParam);  // 在指定路径不存在的情况下将其创建出来  
            if (destParam.endsWith(File.separator)) {  
                String fileName = "";  
                if (srcFile.isDirectory()) {  
                    fileName = srcFile.getName();  
                } else {  
                    fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));  
                }  
                destParam += fileName + ".zip";  
            }  
        }  
        return destParam;  
    }  
      
    /** 
     * 在必要的情况下创建压缩文件存放目录,比如指定的存放路径并没有被创建 
     * @param destParam 指定的存放路径,有可能该路径并没有被创建 
     */  
    private static void createDestDirectoryIfNecessary(String destParam) {  
        File destDir = null;  
        if (destParam.endsWith(File.separator)) {  
            destDir = new File(destParam);  
        } else {  
            destDir = new File(destParam.substring(0, destParam.lastIndexOf(File.separator)));  
        }  
        if (!destDir.exists()) {  
            destDir.mkdirs();  
        }  
    }
    
	/*
	 * 文件操作 返回不带扩展名的文件名
	 */
	public static String getFileNameNoEx(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length()))) {
				return filename.substring(0, dot);
			}
		}
		return filename;
	}
 
}  

pom.xml 依赖:

<!-- zip处理工具包 -->
		<dependency>
			<groupId>net.lingala.zip4j</groupId>
			<artifactId>zip4j</artifactId>
			<version>1.3.2</version>
		</dependency>

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot + zip4j 实现多文件批量下载并压缩 的相关文章

  • Ubuntu: AppImage格式安装、卸载

    我们在linux ubuntu 上最常见到的一种软件包就是deb xff0c 我们可以使用linux的包管理器来进行安装 卸载 xff0c 这个过程提供了很好的GUI界面 xff0c 所以很轻松 但是 xff0c 有时候我们会遇到AppIm
  • VSCode:使用CMakeLists.txt构建C++项目

    vscode配置 插件 xff1a CMake插件主要功能是CMake语法高亮 自动补全CMake Tools的功能主要是结合VSCode IDE使用CMake这个工具 xff0c 比如生成CMake项目 构建CMake项目等CMake T
  • SQL:如何插入JSON数据与返回JSON数据

    什么是JSON JSON xff08 JavaScript Object Notation xff09 是一种轻量级的数据交换语言 xff0c 并且是独立于语言的文本格式 一些NoSQL数据库选择JSON作为其数据存储格式 xff0c 比如
  • python3用Selenium驱动火狐浏览器GeckoDriver安装教程

    前面讲到了谷歌浏览器ChromeDriver的安装 xff0c 今天我们来讲讲火狐浏览器GeckoDviver的安装 xff0c 那么对于 Firefox 来说 xff0c 也可以使用同样的方式完成 Sclenium的对接 xff0c 这时
  • Android Sqlite 读取数据99999.99变为100000.00,出现科学计数法

    问题描述 xff1a 将99999 99 存入Sqlite数据库 xff0c 类型为DECIMAL 6 3 通过cursor getString 变为100000 00 且存储亿位数据时 xff1a cursor getString 会出现
  • iOS OC的基本视图创建-UIView

    1 一般UIView 创建 UIView cellView 61 UIView alloc init superView addSubview cellView cellView layer cornerRadius 61 25 ViewW
  • realvnc免费版,细数4款超好用的realvnc免费版

    RealVNC是VNC xff08 Virtual Network Computing xff09 众多操作平台版本中的一员 xff0c 是互联网上比较流行的远程控制软件 它包括vnc4server和vnc4viewer两个部分 xff0c
  • linux系统实现路由功能

    概述 xff1a 1 在完成4台设备ip配置后默认路由有 路由器Rocky02上默认有 xff1a 192 168 10 0 172 20 0 0 路由器Rocky03上默认有 xff1a 192 168 10 0 10 0 0 0 主机R
  • TT 的旅行日记(Dijkstra)

    问题描述 xff1a 众所周知 xff0c TT 有一只魔法猫 今天他在 B 站上开启了一次旅行直播 xff0c 记录他与魔法猫在喵星旅游时的奇遇 TT 从家里出发 xff0c 准备乘坐猫猫快线前往喵星机场 猫猫快线分为经济线和商业线两种
  • 猫猫向前冲(拓扑排序)

    问题描述 xff1a 有一天 xff0c TT 在 B 站上观看猫猫的比赛 一共有 N 只猫猫 xff0c 编号依次为1 xff0c 2 xff0c 3 xff0c xff0c N进行比赛 比赛结束后 xff0c Up 主会为所有的猫猫从前
  • HRZ的序列

    问题描述 xff1a 相较于咕咕东 xff0c 瑞神是个起早贪黑的好孩子 xff0c 今天早上瑞神起得很早 xff0c 刷B站时看到了一个序列a xff0c 他对这个序列产生了浓厚的兴趣 xff0c 他好奇是否存在一个数K xff0c 使得
  • 东东学打牌

    问题描述 xff1a 最近 xff0c 东东沉迷于打牌 所以他找到 HRZ ZJM 等人和他一起打牌 由于人数众多 xff0c 东东稍微修改了亿下游戏规则 xff1a 所有扑克牌只按数字来算大小 xff0c 忽略花色 每张扑克牌的大小由一个
  • 咕咕东的目录管理器

    文章目录 问题描述样例输入样例输出 解题思路代码 问题描述 咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响 xff0c 时不时发生故障 xff0c 他受不了了 xff0c 想要写一个高效易用零bug的操作系统 这工程量太大了 xff0
  • 针对CSP-T1,T2的练习

    文章目录 题目1问题描述样例输入样例输出 解题思路代码 题目2问题描述样例输入样例输出 解题思路代码 题目1 问题描述 给出n个数 xff0c zjm想找出出现至少 n 43 1 2次的数 xff0c 现在需要你帮忙找出这个数是多少 xff
  • Rust的控制流:条件、循环以及模式匹配

    文章目录 条件控制循环控制forwhileloopbreak continue 模式匹配 条件控制 Rust的条件控制也是使用if else xff0c 和其他语言相比没有多大区别 xff0c 直接看例子 xff1a fn main let
  • 在Windows上搭建Rust开发环境——Clion篇

    文章目录 在Windows上搭建Rust开发环境 Clion篇安装mingw64安装Rusthello world安装Clion使用Clion创建并调试项目 在Windows上搭建Rust开发环境 Clion篇 刚开始学习Rust的时候 x
  • 洛谷P3366最小生成树模板

    kruskal span class token macro property span class token directive keyword include span span class token string lt cstdi
  • 在家远程控制 少了它俩简直太遗憾了

    互联网公司的值班 xff0c 本意在于出现问题时有人及时处理 xff0c 毕竟上线运行的产品 xff0c 出问题可能会影响到公司的整体收益 虽然工作是965 xff0c 但值班日程表却明明白白写着谁负责保障今天的产品运行正常 涉及到技术 运
  • Openstack Kolla-Ansible安装部署

    Openstack Kolla Ansible安装部署 部署节点制作 环境准备 CentOS环境安装 配置国内pypi源 xff1a mkdir p config pip vim config pip pip conf global ind
  • Windows 远程桌面登录蓝屏、不显示桌面问题解决方法

    远程桌面登录蓝屏 不显示桌面问题解决方法 有时候的不当操作 xff0c 可以使Windows服务器或vps远程桌面出现蓝屏或者黑屏 xff01 遇到此问题 xff0c 不要急急忙忙的让机房值班给你重启机器 xff0c 因为此时除了远程连接不

随机推荐

  • 【5G核心网】5GC核心网之网元UPF

    UPF xff08 User Plane Function xff0c 用户面功能 xff09 xff1a ts 29 244 23 501 5 8 1 UPF User Plane Function 用户平面功能 用于RAT内 RAT间移
  • 玩转ADB命令(ADB命令使用大全)

    此文章内容整合自网络 xff0c 欢迎转载 我相信做Android开发的朋友都用过ADB命令 xff0c 但是也只是限于安装应用push文件和设备重启相关 xff0c 更深的就不知道了 xff0c 其实我们完全可以了解多一点 xff0c 有
  • Ubuntu12.04操作系统安装时,出现的问题及解决方案

    问题一 Windows 下用 putty 连接不上虚拟机上的 Ubuntu12 04 解决方案 预探索 问题可能的原因 A 先确定你能不能ping通远程的ubuntu或者虚拟机 B 如果还不能登录 xff0c 分析原因是大多数没有真正开启s
  • 获取镜像源来搭建本地Ubuntu14.04源

    针对公司的网络限制 xff0c 可以在局域网内搭建一台本地的ubuntu源 1 修改源配置 换成搜狐源 默认的ubuntu源不如某些国内的源速度快 vi etc apt source list deb http mirrors sohu c
  • Ubuntu Desktop 16 配置ssh远程登录

    文章目录 环境介绍1 安装openssh server2 允许用户登录 xff1b 编辑配置文件3 重启sshd服务并检查状态4 查看Ubuntu主机的IP5 远程登录Ubuntu6 退出远程登录参考文献英语好的同学请忽略 环境介绍 主机系
  • 关闭Linux防火墙

    文章目录 查看防火墙状态临时关闭防火墙禁止开机启动防火墙开启防火墙允许开机启动防火墙关闭防火墙的步骤 查看防火墙状态 CentOS 6 service iptables status CentOS 7 firewall cmd state
  • ubuntu挂载sd卡到分区目录+修改docker镜像存储位置

    ubuntu挂载sd卡到分区目录 43 修改docker镜像存储位置 一 挂载SD卡到 data 1 查看Linux硬盘信息 lsblk 或 fdisk l lsblk 新的硬盘 xff0c 最好删除之前的分区 xff0c 再新建分区 de
  • xRDP "Password failed, error - problem connecting"

    Add this in sesman ini under Xvnc solved my problem param8 61 SecurityTypes param9 61 None This solved my problum sudo n
  • 如何远程公司 上班族必选大集合

    老张是我们销售部的经理 xff0c 为人随和 xff0c 一点架子也没有 xff0c 和我们关系搞的都很好 xff0c 也很袒护我们 xff0c 由于疫情的原因 xff0c 不得已要居家办公了 xff0c 这让同事们都很不适应 xff0c
  • C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

    C语言排序算法之简单交换法排序 xff0c 直接选择排序 xff0c 冒泡排序 xff0c 最近考试要用到 xff0c 网上也有很多例子 xff0c 我觉得还是自己写的看得懂一些 简单交换法排序 1 简单交换法 排序 2 根据序列中两个记录
  • Centos7 防火墙开放端口,查看状态,查看开放端口

    CentOS7 端口的开放关闭查看都是用防火墙来控制的 xff0c 具体命令如下 xff1a 查看防火墙状态 xff1a xff08 active running 即是开启状态 xff09 root 64 WSS bin systemctl
  • C标准库源码解剖(13):输入输出函数stdio.h

    C标准中的I O库是一个比较庞大的库 xff0c 实现也比较复杂 显然I O库的实现是依赖于操作系统的 xff0c 不同的系统上I O库的实现机理是不一样的 glibc中 xff0c I O库的核心实现在libio目录下 有4个头文件lib
  • 开源的多媒体播放器MPV

    最近在网上找到了一个很好用的开源多媒体播放器MPV 它功能强大 免费开源 支持多平台的极简播放器 底层采用了 MPlayer mplayer2 和 FFmpeg 等开源项目 xff0c 支持多种音视频格式 高清视频 GPU 解码 自定义等功
  • 计算机自动更新变灰色,无法修改解决方法。

    第一种办法 xff1a 使用本地组策略配置自动更新 1 单击 开始 xff0c 然后单击 运行 2 键入 gpedit msc xff0c 然后单击确定 3 展开 计算机配置 4 右键单击 管理模板 xff0c 然后单击 添加 删除模板 5
  • vscode 安装go环境无法安装gopls等插件,响应超时、失去连接等问题的简单解决方案

    看错误提示就大概明白 xff0c 是国内无法连接到 golang org 尝试下载了镜像网站 github com golang 里面的 tools 也不靠谱 因为安装时总会缺少非常多的插件 xff0c 导致无法简单地执行 go insta
  • UIImageView的图片居中问题

    我们都知道在ios中 xff0c 每一个UIImageView都有他的frame大小 xff0c 但是如果图片的大小和这个frame的大小不符合的时候会怎么样呢 xff1f 在默认情况 xff0c 图片会被压缩或者拉伸以填满整个区域 通过查
  • mysqld.exe 占了400M内存的问题

    最近遇到了服务器总是停机的问题 xff0c 虽然它自己只有2G的内存 xff0c 不过实际部署的应用访问量非常小 xff0c 也不至于2G就不够用 xff0c 所以开始了给服务器瘦身的计划 看着任务管理器里面的各个进程 xff0c 发现吃内
  • mysql对外数据连接出现1356错误,1130错误!!!

    问题描述 xff1a 供别的电脑连接本机的数据库 xff0c 总是连接不上 报1356错误 最后查阅相关资料说是 xff1a 连接账户没有远程连接权限 xff0c 只能在本机登录 需要更改mysql数据库里面user表格里的host项把lo
  • Python-docx 读写 Word 文档:读取正文、表格文本信息、段落格式、字体格式等

    Python docx 模块读写 Word 文档基础 xff08 三 xff09 xff1a 读取文档文本信息 表格信息 段落格式 字体格式等 前言 xff1a 1 获取文档章节信息 xff1a 2 获取段落文字信息 xff1a 3 获取文
  • SpringBoot + zip4j 实现多文件批量下载并压缩

    重点功能代码 64 Async 34 threadPoolNeo4jTaskExecutor 34 public void batchDownload Long engSid UserDownload entity 查询指定案卷信息 Fil