java解压缩加密

young 496 2022-02-08

对压缩包进行压缩加密、加压解密,通过zip4j工具进行

https://github.com/srikanth-lingala/zip4j

依赖

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.9.1</version>
</dependency>

代码

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ZipStreamInfoDto {
    private InputStream inputStream;
    private String fileName;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ZipDto {
    private Collection<File> files;
   private Collection<File> folders;
   private Collection<ZipStreamInfoDto> streams;
}
@Slf4j
public class ZipUtil {

   public static ZipBuilder createZipFileBuilder() {
      return new ZipBuilder();
   }

    public static void unzip(String zipFile,  String unzipRootPath) throws Exception {
        unzip(new File(zipFile),  unzipRootPath);
    }
   public static void unzip(String zipFile, String password, String unzipRootPath) throws Exception {
      unzip(new File(zipFile), password, unzipRootPath);
   }

    public static void unzip(File zipFile,  String unzipRootPath) throws Exception {
        unzip(zipFile,null,unzipRootPath);
    }

   public static void unzip(File zipFile, String password, String unzipRootPath) throws Exception {
      LocalFileHeader localFileHeader;
      int readLen;
      byte[] readBuffer = new byte[4096];
      log.info("unzip【{}】 begin", zipFile.getName());
      markRootPathDirs(unzipRootPath);
      try (ZipInputStream zipInputStream = initZipInputStream(zipFile, password)) {
         while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
            File extractedFile = createFile(unzipRootPath, localFileHeader);
            try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
               while ((readLen = zipInputStream.read(readBuffer)) != -1) {
                  outputStream.write(readBuffer, 0, readLen);
               }
            }
         }
      }
      log.info("unzip【{}】 end", zipFile.getName());
   }

   public static void zip(String zipFile, String password, ZipDto zipDto) throws Exception {
      zip(zipFile, password, zipDto.getFiles(), zipDto.getFolders(), zipDto.getStreams());
   }

   public static void zip(String zipFile, ZipDto zipDto) throws Exception {
      zip(zipFile, zipDto.getFiles(), zipDto.getFolders(), zipDto.getStreams());
   }

   public static void zip(OutputStream outputStream, String password, ZipDto zipDto) throws Exception {
      zip(outputStream, password, zipDto.getFiles(), zipDto.getFolders(), zipDto.getStreams());
   }

   public static void zip(OutputStream outputStream, ZipDto zipDto) throws Exception {
      zip(outputStream, zipDto.getFiles(), zipDto.getFolders(), zipDto.getStreams());
   }

   public static void zip(OutputStream outputStream, Collection<File> files, Collection<File> folders,
         Collection<ZipStreamInfoDto> streams) throws Exception {
      zip(outputStream, null, files, folders, streams);
   }

   public static void zip(String zipFile, Collection<File> files, Collection<File> folders,
         Collection<ZipStreamInfoDto> streams) throws Exception {
      zip(zipFile, null, files, folders, streams);
   }

   public static void zipFilesWithPath(OutputStream outputStream, String password, Collection<String> files)
         throws Exception {
      zip(outputStream, password, fillFileCollection(files), null, null);
   }

   public static void zipFiles(OutputStream outputStream, String password, Collection<File> files) throws Exception {
      zip(outputStream, password, files, null, null);
   }

   public static void zipFoldersWithPath(OutputStream outputStream, String password, Collection<String> folders)
         throws Exception {
      zip(outputStream, password, null, fillFileCollection(folders), null);
   }

   public static void zipFolders(OutputStream outputStream, String password, Collection<File> folders)
         throws Exception {
      zip(outputStream, password, null, folders, null);
   }

   public static void zipStreams(OutputStream outputStream, String password, Collection<ZipStreamInfoDto> streams)
         throws Exception {
      zip(outputStream, password, null, null, streams);
   }

   public static void zipFiles(String zipFile, String password, Collection<File> files) throws Exception {
      zip(zipFile, password, files, null, null);
   }

   public static void zipFolders(String zipFile, String password, Collection<File> folders) throws Exception {
      zip(zipFile, password, null, folders, null);
   }

   public static void zipStreams(String zipFile, String password, Collection<ZipStreamInfoDto> streams)
         throws Exception {
      zip(zipFile, password, null, null, streams);
   }

   public static void zipWithPath(OutputStream outputStream, String password, Collection<String> files,
         Collection<String> folders, Collection<ZipStreamInfoDto> streams) throws Exception {
      ZipDto zipDto = fillZipDto(files, folders, streams);
      zip(outputStream, password, zipDto);
   }

   public static void zipWithPath(String zipFile, String password, Collection<String> files,
         Collection<String> folders, Collection<ZipStreamInfoDto> streams) throws Exception {
      ZipDto zipDto = fillZipDto(files, folders, streams);
      zip(zipFile, password, zipDto);
   }

   public static void zip(OutputStream outputStream, String password, Collection<File> files, Collection<File> folders,
         Collection<ZipStreamInfoDto> streams) throws Exception {
      getDefaultZipBuilder(password, files, folders, streams).zip(outputStream);
   }

   public static void zip(String zipFile, String password, Collection<File> files, Collection<File> folders,
         Collection<ZipStreamInfoDto> streams) throws Exception {
      getDefaultZipBuilder(password, files, folders, streams).zip(zipFile);
   }

   private static ZipDto fillZipDto(Collection<String> files, Collection<String> folders,
         Collection<ZipStreamInfoDto> streams) {
      Collection<File> fileCollection = fillFileCollection(files);
      Collection<File> folderCollection = fillFileCollection(folders);
      return new ZipDto(fileCollection, folderCollection, streams);
   }

   private static Collection<File> fillFileCollection(Collection<String> files) {
      Collection<File> fileCollection = null;
      if (CollectionUtils.isNotEmpty(files)) {
         fileCollection = files.stream().map(File::new).collect(Collectors.toList());
      }
      return fileCollection;
   }

   private static ZipBuilder getDefaultZipBuilder(String password, Collection<File> files, Collection<File> folders,
         Collection<ZipStreamInfoDto> streams) {
      ZipBuilder zipBuilder = createZipFileBuilder().setPassword(password).setEncryptionMethod(EncryptionMethod.AES)
            .setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_128).setFiles(files).setFolders(folders)
            .setStreams(streams);
      return zipBuilder;
   }

   private static ZipInputStream initZipInputStream(File zipFile, String password) throws FileNotFoundException {
      return StringUtils.isBlank(password) ? new ZipInputStream(new FileInputStream(zipFile))
            : new ZipInputStream(new FileInputStream(zipFile), password.toCharArray());
   }

   private static File createFile(String unzipRootPath, LocalFileHeader localFileHeader) throws IOException {
      String fileName = localFileHeader.getFileName();
      if (StringUtils.isNotBlank(unzipRootPath)) {
         fileName = unzipRootPath + "/" + fileName;
      }
      log.info("unzip file {}", fileName);
      File extractedFile = new File(fileName);
      markFileParentDirs(extractedFile);
      return extractedFile;
   }

   private static void markFileParentDirs(File extractedFile) throws IOException {
      if (!extractedFile.exists()) {
         if (extractedFile.isDirectory()) {
            extractedFile.mkdirs();
         } else {
            File parentFile = extractedFile.getParentFile();
            if (!parentFile.exists()) {
               parentFile.mkdirs();
            }
            extractedFile.createNewFile();
         }
      }
   }

   private static void markRootPathDirs(String unzipRootPath) {
      if (StringUtils.isNotBlank(unzipRootPath)) {
         File rootPath = new File(unzipRootPath);
         if (!rootPath.exists()) {
            rootPath.mkdirs();
         }
      }
   }

   /**
    * 提供基础的压缩功能
    */
   @Data
   @Accessors(chain = true)
   public static class ZipBuilder {
      private String password;
      private boolean encryptFiles;
      private CompressionMethod compressionMethod;
      private CompressionLevel compressionLevel;
      private EncryptionMethod encryptionMethod;
      private AesKeyStrength aesKeyStrength;
      private Collection<File> files = new ArrayList<>();
      private Collection<File> folders = new ArrayList<>();
      private Collection<ZipStreamInfoDto> streams = new ArrayList<>();
      private ZipParameters zipParameters = new ZipParameters();

      public void zip(String zipFilePath) throws Exception {
         log.info("zip file to {} begin", zipFilePath);
         try (ZipFile zipFile = initZipFile(zipFilePath)) {
            addFiles(zipFile);
            addFolders(zipFile);
            addStreams(zipFile);
            log.info("zip file to {} end", zipFilePath);
         } catch (Exception e) {
            log.error("zip file to" + zipFilePath + " error", e);
            throw e;
         }
      }

      public void zip(OutputStream outputStream) throws Exception {
         log.info("zip file to outputStream begin");
         try (ZipOutputStream zos = initZipOutputStream(outputStream)) {
            byte[] buff = new byte[4096];
            zipFileToOutputStream(zos, buff);
            zipFolderToOutputStream(zos, folders, buff, "");
            zipStreamToOutputStream(zos, buff);
            zos.flush();
            log.info("zip file to outputStream end");
         } catch (Exception e) {
            log.error("zip file to outputStream error", e);
            throw e;
         }
      }

      public ZipBuilder setPassword(String password) {
         this.password = password;
         setEncryptFiles(StringUtils.isNotBlank(password));
         return this;
      }

      public ZipBuilder setEncryptFiles(boolean encryptFiles) {
         this.encryptFiles = encryptFiles;
         zipParameters.setEncryptFiles(encryptFiles);
         return this;
      }

      public ZipBuilder setCompressionMethod(CompressionMethod compressionMethod) {
         this.compressionMethod = compressionMethod;
         zipParameters.setCompressionMethod(compressionMethod);
         return this;
      }

      public ZipBuilder setCompressionLevel(CompressionLevel compressionLevel) {
         this.compressionLevel = compressionLevel;
         zipParameters.setCompressionLevel(compressionLevel);
         return this;
      }

      public ZipBuilder setEncryptionMethod(EncryptionMethod encryptionMethod) {
         this.encryptionMethod = encryptionMethod;
         zipParameters.setEncryptionMethod(encryptionMethod);
         return this;
      }

      public ZipBuilder setAesKeyStrength(AesKeyStrength aesKeyStrength) {
         this.aesKeyStrength = aesKeyStrength;
         zipParameters.setAesKeyStrength(aesKeyStrength);
         return this;
      }

      public ZipBuilder addFile(String file) {
         files.add(new File(file));
         return this;
      }

      public ZipBuilder addFile(File file) {
         files.add(file);
         return this;
      }

      public ZipBuilder addFolder(String folder) {
         folders.add(new File(folder));
         return this;
      }

      public ZipBuilder addFolder(File folder) {
         folders.add(folder);
         return this;
      }

      public ZipBuilder addStream(InputStream stream, String name) {
         streams.add(new ZipStreamInfoDto(stream, name));
         return this;
      }

      private ZipFile initZipFile(String zipFileDir) {
         return StringUtils.isBlank(password) ? new ZipFile(zipFileDir)
               : new ZipFile(zipFileDir, password.toCharArray());
      }

      private void addStreams(ZipFile zipFile) throws ZipException {
         if (CollectionUtils.isEmpty(streams)) {
            return;
         }
         for (ZipStreamInfoDto ZipStreamInfoDto : streams) {
            zipParameters.setFileNameInZip(ZipStreamInfoDto.getFileName());
            zipFile.addStream(ZipStreamInfoDto.getInputStream(), zipParameters);
            log.debug("zipFile add stream {}", ZipStreamInfoDto.getFileName());
         }
      }

      private void addFolders(ZipFile zipFile) throws ZipException {
         if (CollectionUtils.isEmpty(folders)) {
            return;
         }
         for (File folder : folders) {
            zipFile.addFolder(folder, zipParameters);
            log.debug("zipFile add folder {}", folder.getName());
         }
      }

      private void addFiles(ZipFile zipFile) throws ZipException {
         if (CollectionUtils.isEmpty(files)) {
            return;
         }
         for (File file : files) {
            zipFile.addFile(file, zipParameters);
            log.debug("zipFile add file {}", file.getName());
         }
      }

      private ZipOutputStream initZipOutputStream(OutputStream outputStream) throws IOException {
         return StringUtils.isBlank(password) ? new ZipOutputStream(outputStream)
               : new ZipOutputStream(outputStream, password.toCharArray());
      }

      private void zipStreamToOutputStream(ZipOutputStream zos, byte[] buff) throws IOException {
         if (CollectionUtils.isEmpty(streams)) {
            return;
         }
         int readLen;
         for (ZipStreamInfoDto ZipStreamInfoDto : streams) {
            zipParameters.setFileNameInZip(ZipStreamInfoDto.getFileName());
            zos.putNextEntry(zipParameters);
            try (InputStream inputStream = ZipStreamInfoDto.getInputStream()) {
               while ((readLen = inputStream.read(buff)) != -1) {
                  zos.write(buff, 0, readLen);
               }
            }
            zos.closeEntry();
            log.debug("zipFile add stream {}", ZipStreamInfoDto.getFileName());
         }
      }

      private void zipFolderToOutputStream(ZipOutputStream zos, Collection<File> files, byte[] buff, String parentDir)
            throws IOException {
         if (CollectionUtils.isEmpty(folders)) {
            return;
         }
         int readLen;
         for (File file : files) {
            if (file.isDirectory()) {
               String dirName = file.getName();
               File[] childFiles = file.listFiles();
               if (childFiles != null) {
                  List<File> fileList = Arrays.asList(childFiles);
                  dirName = StringUtils.isNotBlank(parentDir) ? parentDir + "/" + dirName : dirName;
                  zipFolderToOutputStream(zos, fileList, buff, dirName);
               }
            } else {
               String fileName = file.getName();
               fileName = StringUtils.isNotBlank(parentDir) ? parentDir + "/" + fileName : fileName;
               zipParameters.setFileNameInZip(fileName);
               zos.putNextEntry(zipParameters);
               try (InputStream inputStream = new FileInputStream(file)) {
                  while ((readLen = inputStream.read(buff)) != -1) {
                     zos.write(buff, 0, readLen);
                  }
               }
               zos.closeEntry();
               log.debug("zipFile add folderFile {}", file.getName());
            }
         }
      }

      private void zipFileToOutputStream(ZipOutputStream zos, byte[] buff) throws IOException {
         if (CollectionUtils.isEmpty(files)) {
            return;
         }
         int readLen;
         for (File file : files) {
            zipParameters.setFileNameInZip(file.getName());
            zos.putNextEntry(zipParameters);
            try (InputStream inputStream = new FileInputStream(file)) {
               while ((readLen = inputStream.read(buff)) != -1) {
                  zos.write(buff, 0, readLen);
               }
            }
            zos.closeEntry();
            log.debug("zipFile add file {}", file.getName());
         }
      }
   }

}

调用示例

public class TestZip {
   @Test
   public void testZipStream() throws Exception {
      ZipUtil.createZipFileBuilder().setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_128)
            .setCompressionLevel(CompressionLevel.NORMAL).setCompressionMethod(CompressionMethod.DEFLATE)
            .setEncryptionMethod(EncryptionMethod.AES).setEncryptFiles(true).setPassword("123456")
            .addFile("H:/aaa.html").addFile(new File("H:/a.xls")).addFolder("H:/ai")
            .addFolder(new File("H:/leetcode"))
            .addStream(new FileInputStream("H:/YYYYYY.bpmn20.xml"), "YYYYYY.bpmn20.xml")
            .zip(new FileOutputStream("D:/testyoung.zip"));

   }

   @Test
   public void testZipFile() throws Exception {
      ZipUtil.createZipFileBuilder().setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_128)
            .setCompressionLevel(CompressionLevel.NORMAL).setCompressionMethod(CompressionMethod.DEFLATE)
            .setEncryptionMethod(EncryptionMethod.AES).setEncryptFiles(true).setPassword("123456")
            .addFile("H:/aaa.html").addFile(new File("H:/a.xls")).addFolder("H:/ai")
            .addFolder(new File("H:/leetcode"))
            .addStream(new FileInputStream("H:/YYYYYY.bpmn20.xml"), "YYYYYY.bpmn20.xml").zip("D:/testyoung.zip");
   }

   @Test
   public void testZipFileParam() throws Exception {
      ZipParameters zipParameters = new ZipParameters();
      zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_128);
      zipParameters.setCompressionLevel(CompressionLevel.NORMAL);
      zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
      zipParameters.setEncryptionMethod(EncryptionMethod.AES);
      zipParameters.setEncryptFiles(true);
      ZipUtil.createZipFileBuilder().setZipParameters(zipParameters).setPassword("132456").addFile("H:/aaa.html")
            .addFile(new File("H:/a.xls")).addFolder("H:/ai").addFolder(new File("H:/leetcode"))
            .addStream(new FileInputStream("H:/YYYYYY.bpmn20.xml"), "YYYYYY.bpmn20.xml").zip("D:/testyoung.zip");
   }

   @Test
   public void testZipFileWithPath() throws Exception {
      ZipUtil.zipWithPath("D:/testyoung.zip", "123456", Arrays.asList("H:/aaa.html"), Arrays.asList("H:/ai"),
            Arrays.asList(new ZipStreamInfoDto(new FileInputStream("H:/YYYYYY.bpmn20.xml"), "YYYYYY.bpmn20.xml")));

   }

   @Test
   public void testUnzip() throws Exception {
      ZipUtil.unzip(new File("D:/testyoung.zip"), "123456", "D:/testYoungZip");
   }