| @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()); |
| } |
| } |
| } |
| |
| } |