zip解压和压缩

发布时间 2023-06-30 15:14:18作者: 小小书童9527

zip解压和压缩

引言

压缩文件

  • 准备压缩的源文件和目标zip文件的路径

  • 创建FileOutputStreamZipOutputStream对象

  • 创建源文件的FileFileInputStream对象

  • 创建ZipEntry对象,并设置其名称为源文件的名称

  • 使用ZipOutputStreamputNextEntry方法将ZipEntry对象添加到压缩文件中

  • 使用循环读取源文件的内容,并使用ZipOutputStreamwrite方法将内容写入压缩文件中

  • 关闭流对象

解压缩文件

  • 准备解压缩的zip文件路径和目标目录路径

  • 创建目标目录的File对象,如果目录不存在则创建目录

  • 创建ZipInputStream对象,使用FileInputStream和zip文件路径作为参数

  • 使用ZipInputStreamgetNextEntry方法获取zip文件的每个条目ZipEntry

  • 循环处理每个zip条目,获取条目的名称和文件内容,并将内容写入目标目录

  • 关闭流对象

  1. 示例代码

    创建zip工具类:

    import org.springframework.mock.web.MockMultipartFile;
    import org.springframework.web.multipart.MultipartFile;

    import java.io.*;
    import java.nio.charset.Charset;
    import java.util.*;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;


    public class ZipUtil {
       // 解压并返回的key是全路径
       public static Map<String, List<MultipartFile>> unzipAndConvertToMap(File file) throws IOException {
           Map<String, List<MultipartFile>> map = new HashMap<>(); // 存放解压后的图片
           byte[] buffer = new byte[1024];
           ZipInputStream zis = new ZipInputStream(new FileInputStream(file),Charset.forName("GBK"));
           try {
               ZipEntry entry;
               while ((entry = zis.getNextEntry()) != null) {

                   if (!entry.isDirectory() && isImage(entry.getName())) { // 判断当前解压的是否是图片
                       // 获取到全路径名称
                       String allFileName = entry.getName();
                       String[] split = allFileName.split("/");
                       // // 图片名称
                       // String imageName = split[split.length - 1];
                       // // 第一层文件夹名称
                       // String firstFile = split[0];
                       StringBuffer sb = new StringBuffer();
                       for (int i = 1; i < split.length-1; i++) {
                           sb.append(split[i]).append("/");
                      }
                       String folderName = sb.toString();
                       List<MultipartFile> imgList = map.getOrDefault(folderName, new ArrayList<>());
                       ByteArrayOutputStream baos = new ByteArrayOutputStream();
                       int len;
                       while ((len = zis.read(buffer)) > 0) {
                           baos.write(buffer, 0, len);
                      }
                       MultipartFile multipartFile = new MockMultipartFile(entry.getName(), entry.getName(), "", baos.toByteArray());
                       imgList.add(multipartFile);
                       map.put(folderName, imgList);
                  }
              }
          } finally {
               zis.close();
          }
           return map;
      }

       // 解压zip并取出文件夹中的所有image格式数据(仅为一层路径)
       public static Map<String, List<MultipartFile>> unzipAndExtractImages(File file) throws IOException {
           Map<String, List<MultipartFile>> map = new HashMap<>(); // 存放解压后的图片
           byte[] buffer = new byte[1024];
           ZipInputStream zis = new ZipInputStream(new FileInputStream(file),Charset.forName("GBK"));
           try {
               ZipEntry entry;
               while ((entry = zis.getNextEntry()) != null) {

                   if (!entry.isDirectory() && isImage(entry.getName())) { // 判断当前解压的是否是图片

                       String folderName = new File(entry.getName()).getParentFile().getName(); // 获取图片所在的文件夹名称
                       List<MultipartFile> imgList = map.getOrDefault(folderName, new ArrayList<>());
                       ByteArrayOutputStream baos = new ByteArrayOutputStream();
                       int len;
                       while ((len = zis.read(buffer)) > 0) {
                           baos.write(buffer, 0, len);
                      }
                       MultipartFile multipartFile = new MockMultipartFile(entry.getName(), entry.getName(), "", baos.toByteArray());
                       imgList.add(multipartFile);
                       map.put(folderName, imgList);
                  }
              }
          } finally {
               zis.close();
          }
           return map;
      }

       // 判断是否是图片格式
       private static boolean isImage(String fileName) { // 判断当前解压中的文件是否是图片
           String lowerCaseFileName = fileName.toLowerCase();
           return lowerCaseFileName.endsWith(".jpg") || lowerCaseFileName.endsWith(".jpeg") || lowerCaseFileName.endsWith(".png");
      }

       /**
        * MultipartFile 转 File
        *
        * @param file
        * @throws Exception
        */
       public static File multipartFileToFile(MultipartFile file) throws Exception {
           File toFile = null;
           if (file.equals("") || file.getSize() <= 0) {
               file = null;
          } else {
               InputStream ins = null;
               ins = file.getInputStream();
               toFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
               inputStreamToFile(ins, toFile);
               ins.close();
          }
           return toFile;
      }

       /**
        * 删除生成file时产生的临时文件
        * @param file
        */
       public static void delteTempFile(File file) {
           if (file != null) {
               File del = new File(file.toURI());
               del.delete();
          }
      }

       //获取流文件
       private static void inputStreamToFile(InputStream ins, File file) {
           try {
               OutputStream os = new FileOutputStream(file);
               int bytesRead = 0;
               byte[] buffer = new byte[8192];
               while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                   os.write(buffer, 0, bytesRead);
              }
               os.close();
               ins.close();
          } catch (Exception e) {
               e.printStackTrace();
          }
      }

    使用

    • /**
      * 导入zip
      *
      * @param multipartFile
      */
      @Override
      public void importZip(MultipartFile multipartFile) {
         Map<String, List<MultipartFile>> map = null;
         try {
             File file = ZipUtil.multipartFileToFile(multipartFile);
             map = ZipUtil.unzipAndConvertToMap(file);
             ZipUtil.delteTempFile(file); // 此处是坑 在接收zip并转换为File格式的时候 如果不指定位置会在项目的根目录多保留一份zip源文件 自行判断时候保留
        } catch (Exception e) {
             throw new CustomException("解压异常");
        }
         if (StringUtils.isNotEmpty(map)) {
             // 上传附件 绑定到产品
             Set<String> productNames = map.keySet().stream()
                    .filter((productName) -> productName.split("/").length == 2)
                    .map((item)->
                           item.split("/")[1]
                    ).collect(Collectors.toSet());
             if (productNames.size() > 0) {
                 // 判断时候是两层路径 第一层是企业名称 第二层是产品名称
                 List<RlProduct> productList = rlProductMapper.getProductByNames(productNames);
                 for (RlProduct rlProduct : productList) {
                     // 转成map 使用map.get("key") 避免双for循环
                     List<MultipartFile> multipartFiles = map.get(rlProduct.getEnterpriseName()+"/"+rlProduct.getProductName()+"/");
                     MultipartFile[] multipartArray = multipartFiles.toArray(new MultipartFile[multipartFiles.size()]);
                     RlFileAttach rlFileAttach = new RlFileAttach();
                     rlFileAttach.setBusiId(rlProduct.getProductId());
                     rlFileAttach.setBusiType(RoseneConstant.FILE_RL_PRODUCT_PRODUCTIMG);
                     rlFileAttach.setAttachType(RoseneConstant.FILE_RL_ATTACHTYPE_M);
                   
                }
                 // 批量上传
            }
        }
      }

注意事项:

  • 示例代码中的文件路径需要根据实际情况进行修改

  • 在编写代码时要注意异常处理和流的关闭操作,以确保资源的正确释放和防止内存泄漏

    扩展

实现rar格式参考:

Java 代码实现rar解压最全攻略操作junrar依赖版本河蟹驿站的博客-CSDN博客

https://blog.csdn.net/qq_45350099/article/details/131199431