当前位置: 首页 > news >正文

SpringBoot 高效处理图片压缩包:上传、解压与存储实战指南

👉这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:

  • 《项目实战(视频)》:从书中学,往事中“练”

  • 《互联网高频面试题》:面朝简历学习,春暖花开

  • 《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题

  • 《精进 Java 学习指南》:系统学习,互联网主流技术栈

  • 《必读 Java 源码专栏》:知其然,知其所以然

👉这是一个或许对你有用的开源项目

国产Star破10w的开源项目,前端包括管理后台、微信小程序,后端支持单体、微服务架构

RBAC权限、数据权限、SaaS多租户、商城、支付、工作流、大屏报表、ERP、CRMAI大模型、IoT物联网等功能:

  • 多模块:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • 微服务:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK17/21+SpringBoot3、JDK8/11+Spring Boot2双版本

来源:blog.csdn.net/qq_21609191

  • 前言

  • 一、压缩包上传

    • 1、接口实现

    • 2、获取压缩包的文件名和文件路径

  • 二、压缩包解压并保存

    • 1、处理压缩包文件方法

    • 2、接口中实现处理压缩包

  • 三、总结


前言

之前一直用的zip4j来对压缩包进行操作,但后来发现Hutool里面也有ZipUtil,ZipUtil是对java.util.zip做工具化封装

操作起来大同小异,改成了Hutool的ZipUtil,这样就少引用了一个依赖。

相关工具:

www.hutool.cn/docs/#/core/工具类/压缩工具-ZipUtil

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

一、压缩包上传

1、接口实现

在Class上加上@RestController标注此类为控制器类

@PostMapping(“/upload”)标注此方法访问路径为"/upload",访问方法是POST

这边接口接收的内容类型Content-Type 为 multipart/form-data,这边接收时会自行根据参数进行判断

@RequestParam(“zipFile”)注解用来获取 zipFile 字段中对应的内容

首先,先实现一个用于上传文件的post接口,代码如下:

@RestController public class Controller { /** * 压缩包文件上传 * * @param zipFile 压缩包文件 * @return R 返回实体类 */ @PostMapping("/upload") public R upload(@RequestParam("zipFile") MultipartFile zipFile) { //TODO return R.success(); } }

这边上传URL默认为:http://127.0.0.1:8080/upload

2、获取压缩包的文件名和文件路径

这边使用@Value注解获取配置文件application.yml的上传路径config.uploadPath的值

在Class上别忘了加上@Component注解进行组件扫描,这样才能获取到配置文件中的上传路径uploadPath

上传文件的接收参数类型为MultipartFile

代码如下:

//组件扫描注解,用于获取配置文件内容 @Component @RestController publicclass Controller { //获取配置文件中的文件上传物理路径,例:C:/ @Value("${config.uploadPath}") private String uploadPath; /** * 压缩包文件上传 * * @param zipFile 压缩包文件 * @return R 返回实体类 */ @PostMapping("/upload") public R multiFace(@RequestParam("zipFile") MultipartFile zipFile) { //获取文件全名 String fileName = zipFile.getOriginalFilename(); //解压目标文件夹对象(压缩文件解压到此文件夹中) File extractFolder = new File(uploadPath + "extract/"); //压缩包存储目标文件对象 File destFile = new File(uploadPath + fileName); //文件上传路径对象 File fileDirectory = new File(uploadPath); //当上传路径不存在时,生成上传路径 if (!fileDirectory.exists()) { fileDirectory.mkdirs(); } //TODO return R.success(); } }

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

二、压缩包解压并保存

1、处理压缩包文件方法

解压缩步骤:

  • 将上传的压缩包保存至文件夹

  • 解压文件夹中的压缩包到指定目录

  • 获取该目录中所有文件的文件数组对象

代码如下:

/** * 处理压缩包文件 * * @param zipFile 上传压缩包 * @param destFile 指定压缩包路径 * @param extractFolder 解压后文件夹 * @return R 返回实体类 */ private R dealZip(MultipartFile zipFile, File destFile, File extractFolder) { //判断解压后文件夹是否存在 if (!extractFolder.exists()) { //不存在就创建 extractFolder.mkdirs(); } try { //步骤1、把上传的压缩包文件保存到指定压缩包路径 zipFile.transferTo(destFile); } catch (IOException e) { //运行报错直接返回错误信息 return R.failed(e.getMessage()); } //步骤2、调用Hutool的ZipUtil压缩工具类的unzip方法来进行对压缩包文件的解压,解压到指定目录 ZipUtil.unzip(destFile, extractFolder); //解压缩完删除原文件(可不删) destFile.delete(); //步骤3、获取解压后目录下所有的文件 File[] images = extractFolder.listFiles(); //这边对获取到的文件数组进行判空校验 if (images == null || images.length == 0) { //不存在就把压缩文件夹删除(可不删) extractFolder.delete(); return failed("上传失败,压缩包为空"); } //错误文件集合 List<String> nameList = new ArrayList<>(); //这边简单做个jpg图片校验,单个文件全名中不包含jpg的文件添加到错误集合中 stream(images).forEach(image -> { if (!image.getName().contains("jpg")) { nameList.add(image.getName()); } }); //错误集合存在数据就返回错误的文件名集合 if (nameList.size() > 0) { //存在错误图片就把压缩文件夹删除(可不删) extractFolder.delete(); return failed("压缩包文件错误,错误文件如下:" + nameList + ",请修改后再上传"); } //错误集合长度为0时返回解压后文件数组对象 return success(images); }

2、接口中实现处理压缩包

代码如下:

//组件扫描注解,用于获取配置文件内容 @Component @RestController publicclass Controller { //获取配置文件中的文件上传物理路径,例:C:/ @Value("${config.uploadPath}") private String uploadPath; //Service层 @Resource private Service service; /** * 压缩包文件上传 * * @param zipFile 压缩包文件 * @return R 返回实体类 */ @PostMapping("/upload") public R multiFace(@RequestParam("zipFile") MultipartFile zipFile) { //获取文件全名 String fileName = zipFile.getOriginalFilename(); //解压目标文件夹对象(压缩文件解压到此文件夹中) File extractFolder = new File(uploadPath + "extract/"); //压缩包存储目标文件对象 File destFile = new File(uploadPath + fileName); //文件上传路径对象 File fileDirectory = new File(uploadPath); //当上传路径不存在时,生成上传路径 if (!fileDirectory.exists()) { fileDirectory.mkdirs(); } //调用上面【处理压缩包文件方法】得到返回结果 R zipResult = dealZip(zipFile, destFile, extractFolder); //失败就返回错误信息 if (FAIL_CODE == zipResult.getCode()) { return zipResult; } //获取【处理压缩包文件方法】中返回的图片文件数组对象 File[] images = (File[]) zipResult.getData(); //实体类集合 List<Entity> entities = new ArrayList<>(); //这边使用stream对图片文件数组对象进行遍历 stream(images).forEach(image -> { //TODO 这边可以做其他的处理 //这边简单的获取了照片名字的前缀作为id String id = image.getName().split("\\.")[0]; //通过数据库找找此id的信息 Entity entity = service.getById(id); if (entity != null) { //存在此条信息就把此图片拷贝到上传目录中,这边用到Hutool的FileUtil文件工具类的copy文件拷贝方法 FileUtil.copy(image, new File(uploadPath + image.getName()), true); //存在就添加进实体类集合 entities.add(entity); } }); //实体类为空代表在数据库中没有找到对应id的信息 if (entities.size() == 0) { //删除解压缩目录(可不删) extractFolder.delete(); return failed("压缩包内图片无匹配信息"); } //删除解压缩目录(可不删) extractFolder.delete(); //最后数据库根据id更新所有集合实体类的信息 return service.updateBatchById(entities) ? success("压缩包上传成功") : failed("压缩包上传失败"); } }

三、总结

这边项目主要应用是上传人脸的照片压缩包,解压缩后,根据照片的名称前缀为人员id来进行保存,压缩包遍历中可以按照业务需求进行文件区分再进行其他操作。

这些年程序员生涯,发现网上一些解决方案很少有完整的,都是零零散散的,查起来特别费劲,所以自己写解决方案会尽量要求写完整,方便自己也方便别人。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。 谢谢支持哟 (*^__^*)
http://www.jsqmd.com/news/338858/

相关文章:

  • Spring AOP + Guava RateLimiter:我是如何用注解实现优雅限流的?
  • 大模型训练全流程解析:从“书呆子“到“智能体“的蜕变之路
  • 别被“涂颜色”骗了——从「栅栏涂色(Paint Fence)」看动态规划真正的思维方式
  • 谋新篇,启新程-群峰机械30周年庆典暨新综合大楼、新厂房落成典礼圆满成功
  • 混用 @Transactional 和 TransactionTemplate 被怼了,三种事务管理到底怎么选?
  • LangGraph多智能体实战:从零构建专业AI研究助手,附完整代码
  • 信息差永远是最容易上手的生意
  • Python:帧对象
  • 《实时渲染》第2章-图形渲染管线-2.6管线综述
  • 为什么AI人才值钱?月薪1.8万只是开始,普通人如何抓住AI风口实现薪资跃迁
  • 科思顿SCISTON:以技术引领市场,凭口碑赢得电动窗帘销售榜Top1
  • 多卡种兼容读卡器,堪称智能一卡通领域的“全能战士”。其核心价值在于通过一颗硬件,解决了不同时期、不同标准、不同应用下卡片兼容性的终极难题,是实现“一卡通行、一卡通用”理想的物理基础
  • 本杰明·格雷厄姆的工作资本分析技巧
  • 【会员】2014-2025年全国监测站点的逐时空气质量数据(15个指标\Excel\Shp格式)
  • RAGFlow工程师必看:微服务架构设计与企业级部署实践
  • 【KB HOME】联手【德伦学院】湖景别墅餐会暨公益慈善活动
  • 从传统PM到AI产品经理:零基础逆袭大模型时代的完整攻略
  • 用FRET“直播”蛋白质的变脸术:在活细胞中捕捉关键酶PP5的构象动态
  • Si83402BAA-IF,具有低导通电阻的2通道隔离智能开关
  • Binutils工具链演进深度解析:以Readelf为例看版本差异与设计哲学
  • 2026企业自动化运维系统怎么选?五大主流系统核心能力深度对比
  • 从天空涂鸦到真实威胁:ADS-B恶作剧 vs 真正的无线电攻击
  • Thinkphp和Laravel框架的企业员工公务车辆管理系统
  • 【干货分享】为什么你的ChIP-seq信号弱?交联固定没做好!
  • 散文诗【留在镜头里的时光】愚人
  • 【故障排查】KubeSphere 无法连接:Connection Refused 与磁盘满导致的 API Server 崩溃
  • 告别校园IT“救火队”,用统一终端管理为教育减负
  • 把握审稿意见,提升论文录用率
  • P1855 榨取kkksc03
  • 当导弹在天上玩漂移:手把手调教气动力控制