zip4j實現多線程壓縮

使用的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;}@Overridepublic 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;}@Overridepublic 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279285.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279285.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279285.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

非三星手機無法登錄三星賬號_如何解決所有三星手機的煩惱

非三星手機無法登錄三星賬號Samsung is the biggest manufacturer of Android phones in the world, but that doesn’t mean these handsets are perfect out of the box. In fact, most of these phones have several annoyances initially—here’s how to fix many of thes…

設置單元格填充方式_單元格的選擇及設置單元格格式

數據輸入完畢&#xff0c;接下來可以設置字體、對齊方式、添加邊框和底紋等方式設置單元格格式&#xff0c;從而美化工作表。要對單元格進行設置&#xff0c;首先要選中單元格。選擇單元格選擇單元格是指在工作表中確定活動單元格以便在單元格中進行輸入、修改、設置和刪除等操…

Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? 要求找到BST中放錯位置的兩個節點. …

springboot三種過濾功能的使用與比較

若要實現對請求的過濾&#xff0c;有三種方式可供選擇&#xff1a;filter、interceptort和aop。本文主要討論三種攔截器的使用場景與使用方式。 下文中的舉例功能是計算每個請求的從開始到結束的時間&#xff0c;例子來源是慕課網。 一、filter 特點&#xff1a;可以獲取原始的…

后綴的形容詞_構詞法(18)構成形容詞的常見后綴 3

即時練習一、按要求改寫下列單詞。1. Japan →___________ adj. 日本(人)的2. Canton →_________ adj. 廣東(人)的3. Vietnam →__________ adj. 越南(人)的4. Europe →__________ adj. 歐洲(人)的5. India → ________ adj. 印度(人)的6. Africa →_______ adj. 非洲(人)的7…

CentOS 桌面啟動無登錄界面

最近VMWare下搞了2個CentOS 32bit虛擬機, 裝了些軟件之后&#xff0c;都遇到開機無法顯示登錄界面&#xff0c; 僅能看見桌面背景圖的情況。 以下是我搜索很久匯總的方法。 嘗試按 ctrl alt F3(快捷鍵可能有所不同), 由桌面模式進入命令行模式。 直接 startx 報錯&#xf…

批量刪除推文_如何搜索(和刪除)您的舊推文

批量刪除推文“The internet never forgets” is an aphorism that isn’t entirely true, but it’s worth thinking about whenever you post to social media. If you think your Twitter profile needs a bit of a scrub, here’s how to search and delete those old twee…

[USACO13JAN] Cow Lineup (單調隊列,尺取法)

題目鏈接 Solution 尺取法板子,算是復習一波. 題中說最多刪除 \(k\) 種,那么其實就是找一個顏色種類最多為 \(k1\) 的區間; 統計一下其中最多的顏色出現次數. 然后直接尺取法,然后每次對于 \(col[r]\) 進行統計,時間復雜度 \(O(n)\) . Code #include<bits/stdc.h> using …

智能記憶功能nest_如何設置和安裝Nest Protect智能煙霧報警器

智能記憶功能nestIf you want to add a bit more convenience and safety to your home’s smoke alarm setup, the Nest Protect comes with a handful of great features to make that a reality. Here’s how to set it up and what all you can do with it. 如果您想為您的…

網格自適應_ANSYS 非線性自適應(NLAD)網格劃分及應用舉例

文章來源&#xff1a;安世亞太官方訂閱號&#xff08;搜索&#xff1a;Peraglobal&#xff09;在復雜的結構設計分析中&#xff0c;通常很難確定在高應力區域中是否生成適當的細化網格。在做非線性大應變分析仿真時&#xff0c;可能由于單元變形過大&#xff0c;導致網格畸變&a…

js繼承優化

在看《js設計模式》中&#xff0c;作者提到了js中的兩種繼承方式&#xff1a;類繼承 或 原型繼承&#xff0c;或許是本人才疏學淺&#xff0c;竟發現一些問題。 一、類繼承 思路&#xff1a;作者的思路是使用基于類來繼承&#xff0c;并且做了一個extend函數&#xff0c;在第一…

python---[列表]lsit

內置數據結構&#xff08;變量類型&#xff09; -list -set -dict -tuple -list&#xff08;列表&#xff09; -一組又順序的數據組合 -創建列表 -空列表 list1 []        print(type(list1))        print(list1)        list2 [100]       …

喚醒計算機運行此任務_如何停止Windows 8喚醒計算機以運行維護

喚醒計算機運行此任務Windows 8 comes with a new hybrid boot system, this means that your PC is never really off. It also means that Windows has the permission to wake your PC as it needs. Here’s how to stop it from waking up your PC to do maintenance tasks…

轉整型_SPI轉can芯片CSM300詳解、Linux驅動移植調試筆記

一口君最近移植了一款SPI轉CAN的芯片CSM300A&#xff0c;在這里和大家做個分享。一、CSM300概述CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模塊。1. 簡介CSM300(A)系列隔離 SPI / UART 轉 CAN 模塊是集成微處理器、 CAN 收發器、 DC-DC 隔離電源、 信號隔離于一體的通信…

matlab練習程序(二值圖像連通區域標記法,一步法)

這個只需要遍歷一次圖像就能夠完全標記了。我主要參考了WIKI和這位兄弟的博客&#xff0c;這兩個把原理基本上該介紹的都介紹過了&#xff0c;我也不多說什么了。一步法代碼相比兩步法真是清晰又好看&#xff0c;似乎真的比兩步法要好很多。 代碼如下&#xff1a; clear all; c…

pc微信不支持flash_在出售PC之前,如何取消對Flash內容的授權

pc微信不支持flashWhen it comes to selling your old digital equipment you usually should wipe it of all digital traces with something like DBAN, however if you can’t there are some precautions you should take–here’s one related to Flash content you may h…

博客在線——Wireshark基本用法

http://blog.jobbole.com/ http://blog.jobbole.com/70907/轉載于:https://www.cnblogs.com/zhongbokun/p/9709326.html

繪制三維散點圖_SPSS統計作圖教程:三維散點圖

作者&#xff1a;豆沙包&#xff1b;審稿&#xff1a;張耀文1、問題與數據最大攜氧能力是身體健康的一項重要指標&#xff0c;但檢測該指標成本較高。研究者想根據性別、年齡、體重、運動后心率等指標建立預測最大攜氧能力的模型&#xff0c;招募了100名研究對象&#xff0c;測…

【Python】插入sqlite數據庫

import sqlite3 from datetime import datetimeconn sqlite3.connect(data.db) print("Opened database successfully")for i in range(100):time datetime.now()conn.execute("INSERT INTO test(time,url,imgPath) VALUES (?,?,?)", (time, "ww…

java數組轉list(Arrays .asList)

習慣性的錯誤代碼&#xff1a; Integer[] intArr {1,2,3}; List<Integer> lst Arrays .asList(intArr); lst.add(4); 報UnsupportedOperationException異常&#xff0c;原因是Arrays .asList() 返回的固定大小的列表&#xff0c;無法進行add、remove等操作&#xff1b;…