使用的jar包:zip4j_1.3.2.jar 基本功能: 針對ZIP壓縮文件創建、添加、分卷、更新和移除文件 (讀寫有密碼保護的Zip文件) (支持AES 128/256算法加密) (支持標準Zip算法加密) (支持zip64格式) (支持Store(僅打包,默認不壓縮,不過可以手動設置大小)和Deflate壓縮方法 (針對分塊zip文件創建和抽出文件) (支持編碼) (進度監控) 壓縮方式(3種): static final int COMP_STORE = 0;(僅打包,不壓縮) (對應好壓的存儲) static final int COMP_DEFLATE = 8;(默認) (對應好壓的標準) static final int COMP_AES_ENC = 99;
壓縮級別有5種:(默認0不壓縮)級別跟好壓軟件是對應的; static final int DEFLATE_LEVEL_FASTEST = 1; static final int DEFLATE_LEVEL_FAST = 3; static final int DEFLATE_LEVEL_NORMAL = 5; static final int DEFLATE_LEVEL_MAXIMUM = 7; static final int DEFLATE_LEVEL_ULTRA = 9; 加密方式: static final int ENC_NO_ENCRYPTION = -1;(默認,沒有加密方法,如果采用此字段,會報錯”沒有提供加密算法”) static final int ENC_METHOD_STANDARD = 0; static final int ENC_METHOD_AES = 99; AES Key Strength: (默認-1,也就是ENC_NO_ENCRYPTION) static final int AES_STRENGTH_128 = 0x01; static final int AES_STRENGTH_192 = 0x02; static final int AES_STRENGTH_256 = 0x03;
從構造方法可以默認情況: compressionMethod = Zip4jConstants.COMP_DEFLATE; encryptFiles = false;//不設密碼 readHiddenFiles = true;//可見 encryptionMethod = Zip4jConstants.ENC_NO_ENCRYPTION;//加密方式不加密 aesKeyStrength = -1;// includeRootFolder = true;// timeZone = TimeZone.getDefault();//
***
情景教學壓縮操作類 */
public class CompressHandler
extends Thread { private Logger logger = Logger.getLogger(CompressHandler.
class ); /** * 存儲目錄名和對應目錄下的文件地址 */ private Map<String, List<ResourceInfo>>
resourceMap; /** * 壓縮類中的配置文件 */ private String configJson; /** * 配置文件map key為壓縮包中的文件名,value為文件內容 */ Map <String, String>
configJsonMap; /** * 回調接口 */ private ZipOperate zipOperate; /** * 加密標志 */ private boolean encrypt =
false ; /** * 線程名稱 */ private String threadName =
Thread.currentThread().getName(); /** * 取消標志 */ private boolean cancelFlag; public CompressHandler() {} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String>
configJsonMap, ZipOperate zipOperate) { this (resourceMap, configJsonMap, zipOperate,
false );} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String> configJsonMap, ZipOperate zipOperate,
boolean encrypt) { this .resourceMap =
resourceMap; this .configJsonMap =
configJsonMap; this .zipOperate =
zipOperate; this .encrypt =
encrypt;} public CompressHandler(Map<String, List<ResourceInfo>>
resourceMap, String configJson, ZipOperate zipOperate) { this (resourceMap, configJson, zipOperate,
false );} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, String configJson, ZipOperate zipOperate,
boolean encrypt) { this .resourceMap =
resourceMap; this .configJson =
configJson; this .zipOperate =
zipOperate; this .encrypt =
encrypt;}@Override public void run() { if (zipOperate !=
null ) {zipOperate.beforeCompress();}String fileName = UUID.randomUUID().toString().replace("-", "").concat(".zip"
);String tempDir =
SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TMMP_FILE_PATH);File tempDirFile =
new File(tempDir); if (!
tempDirFile.exists()) {tempDirFile.mkdir();}String filePath = tempDir.concat("/"
).concat(fileName); // 存儲生成本地壓縮包的文件 List<File> encryptFileList =
new ArrayList<>
(); try {ZipFile zipFile =
new ZipFile(filePath);logger.info( "線程" + threadName + " 開始壓縮,壓縮的文件名為:" +
fileName); long startTime =
System.currentTimeMillis();logger.info( "線程" + threadName + " 開始時間為:" +
startTime);ZipParameters parameters =
new ZipParameters(); // 設置壓縮方式和壓縮級別
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 當開啟壓縮包密碼加密時 boolean dirEncrypt =
false ; if (encrypt ||
Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.ENABLE_ENCRYPT_ZIP))) {logger.info( "線程" + threadName + " 該壓縮包需要加密"
);addEncryptParameters(parameters);dirEncrypt =
true ;} for (String dir : resourceMap.keySet()) {logger.info( "線程" + threadName + " 添加目錄:" +
dir);List <ResourceInfo> resourceInfoList =
resourceMap.get(dir); for (ResourceInfo resourceInfo : resourceInfoList) {String resourceFileName =
resourceInfo.getFileName();logger.info( "線程" + threadName + " 添加文件:" +
resourceFileName); /** * 20180921判斷目錄名是否為空字符串 true不創建目錄 by lizhang10 */ if (StringUtils.isNotEmpty(dir)){parameters.setFileNameInZip(dir + "/" +
resourceFileName);} else {parameters.setFileNameInZip(resourceFileName);}parameters.setSourceExternalStream( true );InputStream inputStream =
resourceInfo.getInputStream(); if (inputStream ==
null ) { // 獲取文件流 String fileUrl =
resourceInfo.getFileUrl(); long startTime1 =
System.currentTimeMillis();logger.info( "線程" + threadName + " 開始獲取文件流,地址:" + fileUrl + " 開始時間:" +
startTime1);inputStream =
getInputStream(fileUrl); long endTime1 =
System.currentTimeMillis();logger.info( "線程" + threadName + " 結束獲取文件流,地址:" + fileUrl + " 結束時間:" + endTime1 + " 耗時毫秒: " + (endTime1 -
startTime1));} // 當壓縮包沒有加密時,則從文件屬性中取是否進行加密 if (!dirEncrypt &&
resourceInfo.isEncrypt()){ // 如果是zip的話,則對文件進行解壓,然后再加密 if (resourceFileName.endsWith(".zip"
)){ long saveStartTime =
System.currentTimeMillis(); // 網絡文件路徑 String sourceFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip"
));logger.info( "線程" + threadName + " 該文件["+resourceFileName+"]是zip且需要加密,開始存到本地,路徑為:"+sourceFileName+"開始時間:" +
saveStartTime); // 加密文件路徑 String encryptFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip"
));File file =
new File(sourceFileName);FileOutputStream outputStream =
new FileOutputStream(file); byte [] buffer =
new byte [8*1024
]; int len = 0
; while ((len = inputStream.read(buffer)) != -1
){outputStream.write(buffer, 0
,len);}outputStream.close();inputStream.close(); long saveEndTime =
System.currentTimeMillis();logger.info( "線程" + threadName + " 該文件是zip,存到本地完成,結束時間:" + saveEndTime + " 耗時:"+(saveEndTime -
saveStartTime)); long extractStartTime =
System.currentTimeMillis();logger.info( "線程" + threadName + " ,開始進行解壓加密,開始時間為:" +
extractStartTime);ZipFile sourceZipFile =
new ZipFile(file);String extractDir = tempDir.concat("/"
).concat(UUID.randomUUID().toString());sourceZipFile.extractAll(extractDir); long extractEndTime =
System.currentTimeMillis();ZipFile encryptZipFile =
new ZipFile(encryptFileName);ZipParameters parameters2 =
new ZipParameters(); // 設置壓縮方式和壓縮級別
parameters2.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);parameters2.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);addEncryptParameters(parameters2); // 添加獲取文件的文件和目錄 File[] fileArray =
new File(extractDir).listFiles(); for (File file1 : fileArray) { if (file1.isDirectory()){encryptZipFile.addFolder(file1,parameters2);} else {encryptZipFile.addFile(file1,parameters2);}} if (!
StringUtils.isEmpty(resourceInfo.getConfigJson())){parameters2.setFileNameInZip( "config.json"
);parameters2.setSourceExternalStream( true );encryptZipFile.addStream( new ByteArrayInputStream(resourceInfo.getConfigJson().getBytes("utf8"
)),parameters2);}logger.info( "線程" + threadName + " ,完成解壓加密,結束時間為:" + extractEndTime + " 耗時: " + (extractEndTime-
extractStartTime)); // 刪除文件
sourceZipFile.getFile().delete(); // 刪除目錄下的文件 deleteFolder(
new File(extractDir));File encryptFile =
encryptZipFile.getFile();inputStream =
new FileInputStream(encryptFile);encryptFileList.add(encryptFile);}} // 獲取需要打包的文件流
zipFile.addStream(inputStream, parameters);inputStream.close();}}parameters.setSourceExternalStream( true ); // 如果configJsonMap不為空,且length不為0,則遍歷加入到壓縮包中 if (configJsonMap !=
null && configJsonMap.size() > 0
) { for (String resourceName : configJsonMap.keySet()) {logger.info( "線程" + threadName + " 添加配置文件" +
resourceName);parameters.setFileNameInZip(resourceName);String value =
configJsonMap.get(resourceName);zipFile.addStream( new ByteArrayInputStream(value.getBytes("utf8"
)), parameters);}} if (!
StringUtils.isEmpty(configJson)) {logger.info( "線程" + threadName + " 添加文件config.json"
);parameters.setFileNameInZip( "config.json"
);zipFile.addStream( new ByteArrayInputStream(configJson.getBytes("utf8"
)), parameters);}logger.info( "線程" + threadName + " 壓縮文件" + fileName + "完成"
); long endTime =
System.currentTimeMillis();logger.info( "線程" + threadName + " 結束時間為:" + endTime + " 耗時毫秒:" + (endTime -
startTime)); long startTime2 =
System.currentTimeMillis();logger.info( "線程" + threadName + " 開始將壓縮包上傳到文件服務.......開始時間:" +
startTime2);FileInfo fileInfo =
new CystrageUtil().uploadToRemoteServer(fileName, filePath,
null ); long endTime2 =
System.currentTimeMillis();logger.info( "線程" + threadName + " 上傳完成.......結束時間:" + endTime2 + "耗時毫秒: " + (endTime2 -
startTime2)); if (cancelFlag){ throw new InterruptedException("線程" + threadName + " 取消壓縮"
);} // 如果傳入了后續操作接口,則將文件服務返回的類傳入 if (zipOperate !=
null ) {zipOperate.afterCompress(fileInfo, zipFile);zipFile.getFile().delete();}} catch (Exception e) {logger.error( "線程" + threadName + " 文件壓縮出錯...........文件內容:" +
configJson, e); if (zipOperate !=
null ) {zipOperate.errorCompress();} // 刪除對應壓縮包 new File(filePath).delete();} finally { try { // 關流
inputStream.close();} catch (IOException e) {inputStream =
null ;} // 刪除本地生成的壓縮文件 // 存儲生成本地壓縮包的文件 for (File file : encryptFileList) {file.delete();}}} /** * 刪除文件夾下的所有文件* @param sourceDir */ private void deleteFolder(File sourceDir) { if (sourceDir.isDirectory()){File[] files =
sourceDir.listFiles(); for (File file : files) {deleteFolder(file);}} else {sourceDir.delete();}sourceDir.delete();} private void addEncryptParameters(ZipParameters parameters) {String password =
SuperdiamondConfig.getConfig(SuperdiamondConfig.ZIP_COMPRESS_PASSWORD);parameters.setEncryptFiles( true );parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);parameters.setPassword(password.toCharArray());} /** * 獲取輸入流** @param fileUrl* @return */ InputStream inputStream; private InputStream getInputStream(String fileUrl)
throws Exception { if (cancelFlag){ throw new InterruptedException("線程" + threadName + " 取消壓縮"
);} int retry = 1
; while (retry <= 3
) { try { int index = fileUrl.lastIndexOf("/"
);String prefix = fileUrl.substring(0, index + 1
);String fileName = fileUrl.substring(index + 1
);URL url =
new URL(prefix + URLEncoder.encode(fileName, "utf8"
));URLConnection connection =
url.openConnection();connection.setDoInput( true );inputStream =
connection.getInputStream(); return inputStream;} catch (Exception e) { if (retry == 1
) {logger.error( "線程" + threadName + " 獲取文件出錯,文件地址:" +
fileUrl, e);}logger.error( "開始重試第" + retry + "次"
); // 由于測試環境服務器承載能力比較差,當獲取失敗后,睡眠一段時間再重試 if (Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TEST_ENVIRONMENT))){Thread.currentThread().sleep(Long.parseLong(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_SLEEP_TIME)));} if (retry == 3
) { throw new Exception(e);}retry ++
;}} return null ;} public void setCancelFlag(Boolean cancelFlag){ this .cancelFlag =
cancelFlag;}@Override public void interrupt() { if (inputStream !=
null ) { try {inputStream.close();} catch (IOException e) {inputStream =
null ;logger.info( "線程" + threadName + " 關閉io流失敗"
);}} super .interrupt();} public static class ResourceInfo { /** * 文件名稱 */ private String fileName; /** * 文件地址 */ private String fileUrl; /** * 輸入流 */ private InputStream inputStream; /** * 是否要為當前文件添加config,json */ private String configJson; /** * 改文件是否加密 */ private boolean encrypt; public InputStream getInputStream() { return inputStream;} public void setInputStream(InputStream inputStream) { this .inputStream =
inputStream;} public String getFileName() { return fileName;} public void setFileName(String fileName) { this .fileName =
fileName;} public String getFileUrl() { return fileUrl;} public void setFileUrl(String fileUrl) { this .fileUrl =
fileUrl;} public boolean isEncrypt() { return encrypt;} public void setEncrypt(
boolean encrypt) { this .encrypt =
encrypt;} public String getConfigJson() { return configJson;} public void setConfigJson(String configJson) { this .configJson =
configJson;}}
} ?
轉載于:https://www.cnblogs.com/AnonymouL/p/9700368.html
總結
以上是生活随笔 為你收集整理的zip4j实现多线程压缩 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。