(总目录)springboot - 实现zip文件上传并对zip文件解压, 包含上传oss
作者:mmseoamin日期:2023-12-19

全文目录,一步到位

  • 1.本文概述
    • 1.1 本文简介
    • 2. 功能实现
      • 2.1 统一文件校验
      • 2.2 普通(多)文件上传[服务器]
        • 2.2.1 controller层
        • 2.2.2 service层
        • 2.2.3 业务impl实现类
        • 2.2.4 FileIOUtils工具包代码
        • 2.3 zip文件的解压
        • 2.4 图片文件的压缩
        • 2.5 oss文件后端上传
        • 2.6 oss文件前端上传
        • 2.7 后端工具测试
        • 3. 本文异常总结
          • 3.1 异常总结
            • 3.1.1 文件解压的时候报错解决
            • 3.1.2 读取文件 报 无权限访问
            • 3.2 oss上传异常
            • 4. 文章总结与预告
              • 4.1 本文总结
              • 4.2 下文预告

                1.本文概述

                1.1 本文简介

                本文会包含

                • java 文件校验
                • 文件上传
                • 文件压缩
                • zip文件的解压
                • oss的文件上传
                • oss前端上传

                2. 功能实现

                文章像齿轮一样, 部分位置需要自己组装满足不同业务需求

                需要哪个就加哪个 注意类型和位置即可 注释都是很全的

                如果在使用中 遇到问题 欢迎评论区指正

                2.1 统一文件校验

                ===> 传送门: MultipartFile 统一文件校验

                2.2 普通(多)文件上传[服务器]

                支持单/多文件同时上传 部分service方法 这个都随意 满足springboot标准即可

                2.2.1 controller层

                    /**
                     * 普通文件上传
                     * @param
                     * @return
                     */
                    @ApiOperation("==> 普通文件上传 <===")
                    @RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
                    public ResultResponse fileUpload(MultipartFile[] file, PageVo pageVo) {
                        log.info("===> 普通文件上传 <===");
                        ResultResponse result = ossAddService.fileUpload(file, pageVo.getSearchName());
                        log.info("返回用户信息:{}", result);
                        return result;
                    }
                

                2.2.2 service层

                 ResultResponse fileUpload(MultipartFile[] file, String searchName);
                

                2.2.3 业务impl实现类

                 	@SneakyThrows
                    @Override
                    public ResultResponse fileUpload(MultipartFile[] file, String searchName) {
                        //文件上传功能
                        String str = FileIOUtils.fileUpload(file, searchName, false);
                        return ResultResponse.ok().setData(str);
                    }
                

                2.2.4 FileIOUtils工具包代码

                注意: 有报错的位置 注释掉即可 , 自己的业务代码

                • throw异常位置 换成 RuntimeException(“我是异常”) 即可
                • ZipUtil.unzip() 解压的方法 根据后缀名 是zip进行解压

                  后面有介绍->2.3 不需要可以直接注释

                import lombok.SneakyThrows;
                import lombok.extern.slf4j.Slf4j;
                import org.apache.commons.compress.utils.IOUtils;
                import org.springframework.web.multipart.MultipartFile;
                import java.io.File;
                import java.io.FileOutputStream;
                import java.io.IOException;
                import java.util.Objects;
                import java.util.UUID;
                /**
                 * 文件上传工具类
                 *
                 * @author pzy
                 * @version 0.1.0
                 * @description TODO
                 */
                @Slf4j
                public class FileIOUtils {
                    /**
                     * 文件上传
                     *
                     * @param file             上传文件
                     * @param uploadPath       上传文件路径
                     * @param isRandomFileName 是否是随机的文件名 true:是  false:否
                     * @return
                     */
                    @SneakyThrows
                    public static String fileUpload(MultipartFile[] file, String uploadPath, boolean isRandomFileName) {
                        //上传目录地址
                        log.debug(uploadPath);
                        //(最新修改)如果目录不存在,自动创建文件夹(修复)
                        if (!FileIOUtils.createFile(1, new File(uploadPath), false)) {
                            log.error("-------> 自动创建文件或文件夹失败!!! <--------");
                        }
                        //之后可以 优化  根据配置文件自动配置 mkdir-
                        String suffix = null;
                        String fileName = null;
                        //  HashMap hashMap = new HashMap();
                        FileOutputStream fileOutputStream = null;
                        try {
                            //遍历文件数组执行上传(多文件上传需要)
                            for (MultipartFile multipartFile : file) {
                                if (multipartFile != null) {
                                    log.debug("开始上传文件.......");
                                    //调用上传方法
                                    suffix = Objects.requireNonNull(multipartFile.getOriginalFilename()).substring(multipartFile.getOriginalFilename().lastIndexOf(".")); //后缀名
                                    //文件名 是随机 就uuid 不是随机就是原名
                                    fileName = (isRandomFileName ? UUID.randomUUID() + suffix : multipartFile.getOriginalFilename());
                                    fileOutputStream = new FileOutputStream(uploadPath + "/" + fileName);
                                    IOUtils.copy(multipartFile.getInputStream(), fileOutputStream);
                                    //file[i].transferTo(new File(uploadDir+"/"+fileName));
                                    log.debug("上传" + uploadPath + "/" + fileName + "文件成功!");
                                    /*不是随机文件上传 并且是 zip 解压*/
                                    if (!isRandomFileName && Objects.equals(suffix, ".zip")) {
                                        //解压文件夹
                                        ZipUtil.unzip(uploadPath + "/" + fileName, uploadPath);
                                    }
                                }
                            }
                            log.debug("上传结束!所有文件上传文件至:" + uploadPath);
                            System.out.printf("文件名->%s\n", fileName);
                            return fileName;
                        } catch (Exception e) {
                            //打印错误堆栈信息
                            e.printStackTrace();
                            log.error("上传文件失败,请检查后重试!!!");
                            throw new ThirdServiceException(ResponseEnum.T160004);
                        } finally {
                            if (fileOutputStream != null) {
                                fileOutputStream.close();
                            }
                        }
                    }
                    /**
                     * 判断文件是否存在,不存在就创建
                     *
                     * @param file
                     */
                    public static boolean createFile(int type, File file, Boolean flag) {
                        if (type == 1) {
                            if (!file.exists()) {
                                return file.mkdirs();
                            }
                        }
                //其他就是0 文件及目录创建(存在bug)
                        if (file.exists()) {
                            log.debug("文件及相关路径存在!!!");
                        } else {
                            log.info("文件不存在 ,创建文件以及文件夹 ...");
                            //getParentFile() 获取上级目录(包含文件名时无法直接创建目录的)
                            if (!file.getParentFile().exists()) {
                                log.info("文件及其路径不存在, 创建路径文件!!!");
                                //创建层级目录
                                if (!file.getParentFile().mkdirs()) {
                                    return false;
                                }
                            }
                            if (flag) {
                                try {
                                    //上层目录创建文件
                                    log.info("文件夹创建开启,在上层目录下创建文件夹");
                                    if (file.createNewFile()) {
                                        return false;
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                        return true;
                    }
                    /**
                     * 文件删除回收
                     *
                     * @param path
                     */
                    public static boolean fileGCDelete(String path) {
                        boolean flag = false;
                        File file1 = new File(path);
                        if (file1.exists()) {
                            flag = file1.delete();
                            try {
                                do {
                                    if (!flag) {
                                        System.gc();    //回收资源
                                        flag = file1.delete();
                                    }
                                } while (!flag);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            log.debug("路径存在" + flag);
                        }
                        return flag;
                    }
                }
                

                2.3 zip文件的解压

                文件压缩工具包 使用java.util.zip包

                import lombok.extern.slf4j.Slf4j;
                import java.io.File;
                import java.io.FileInputStream;
                import java.io.FileOutputStream;
                import java.io.IOException;
                import java.nio.charset.StandardCharsets;
                import java.util.zip.ZipEntry;
                import java.util.zip.ZipInputStream;
                /**
                 * 解压文件工具类
                 *
                 * @author pzy
                 * @version 0.1.0
                 * @description TODO
                 */
                @Slf4j
                public class ZipUtil {
                    /**
                     * 解压核心功能
                     * @param zipFilePath 文件目标路径
                     * @param destDir 文件解压后路径
                     * @throws IOException
                     */
                    public static void unzip(String zipFilePath, String destDir) throws IOException {
                        log.info("===>开启文件解压: {}",zipFilePath);
                        File dir = new File(destDir);
                        if (!dir.exists()) {
                            boolean mkdirs = dir.mkdirs();
                            if (!mkdirs) {
                                log.error("多级文件夹创建失败===>{}",destDir);
                            }
                        }
                        //windows下中文默认gbk 正常使用utf-8
                        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath), StandardCharsets.UTF_8)) {
                            ZipEntry entry = zipIn.getNextEntry();
                            while (entry != null) {
                                String filePath = destDir + File.separator + entry.getName();
                                if (!entry.isDirectory()) {
                                    extractFile(zipIn, filePath);
                                } else {
                                    File dirToCreate = new File(filePath);
                                    boolean mkdirs = dirToCreate.mkdirs();
                                    if (!mkdirs) {
                                        log.error("多级文件夹创建失败===>{}",filePath);
                                    }
                                }
                                zipIn.closeEntry();
                                entry = zipIn.getNextEntry();
                            }
                        }
                    }
                    /**
                     * 提取文件
                     * @param zipIn ZipInputStream
                     * @param filePath 文件路径
                     * @throws IOException
                     */
                    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
                        try (FileOutputStream fos = new FileOutputStream(filePath)) {
                            byte[] buffer = new byte[1024];
                            int bytesRead;
                            while ((bytesRead = zipIn.read(buffer)) != -1) {
                                fos.write(buffer, 0, bytesRead);
                            }
                        }
                    }
                }
                

                2.4 图片文件的压缩

                ===> 传送门: Thumbnails之上传图片后压缩处理

                2.5 oss文件后端上传

                ===> 传送门1: oss存储对象 文件(视频)上传, 获取回调中的url, 官网地址

                ===> 传送门2: 后端oss存储(完整版) 及 解决删除本地文件显示被占用问题

                2.6 oss文件前端上传

                ===> 传送门: oss前端文件上传, 优势及后端如何配合

                2.7 后端工具测试

                ⇒ 传送门: Postman,ApiPost, Idea httpclient tools,ApiFox 替代swagger,零侵入 接口文档生成

                (总目录)springboot - 实现zip文件上传并对zip文件解压, 包含上传oss,在这里插入图片描述,第1张

                3. 本文异常总结

                3.1 异常总结

                3.1.1 文件解压的时候报错解决

                java.lang.IllegalArgumentException: MALFORMED 解决方法

                • 加charset(utf-8) 不行windows换gbk

                3.1.2 读取文件 报 无权限访问

                两种方法

                • 增加文件夹权限
                • 看看文件路径 是否正确 找没找到想读取的文件

                3.2 oss上传异常

                ===> 传送门: oss报错修改指南

                4. 文章总结与预告

                4.1 本文总结

                注意文件夹路径对应, 解压文件路径, 包括文件路径斜线问题 \\ 和 /

                流用完记得关闭 判断是否为空 避免空指针

                4.2 下文预告

                无预告, 终篇


                作者pingzhuyan 感谢观看