java解壓縮/壓縮/加密壓縮/加密解壓縮 ZIP4J ZIP檔案壓縮與解壓縮學習
阿新 • • 發佈:2018-12-19
最近公司準備讓各專案組提供公共工具元件,手中正好無事便研究其中一個工具 - 檔案壓縮與解壓縮工具。
目前JAVA API已提供對於ZIP檔案的壓縮與解壓縮,但網上總結不支援ZIP檔案加密與解密甚至對於中文支援也有問題,於是果斷找其他的支援加密解密的第三方包。 winzipaes 與 ZIP4J 都符合專案的要求 ,最終選擇ZIP4J來進行使用。
- ZIP4J 是一個支援處理ZIP檔案的開源庫
- 支援建立,修改,新增,刪除,解壓 壓縮檔案
- 支援讀/寫密碼保護
- 支援AES加密 128/256
- 支援標準ZIP加密
- 支援進度監視器
- 自持Unicode 檔名
- 支援建立分卷壓縮檔案
- 支援將檔案新增到壓縮包中但不進行壓縮
目前ZIP4J 版本為:1.3.1 ,只需要直接下一載一個zip4j_1.3.1.jar一個jar包即可,同時可以下載官網提供的例子進行學習,例子相當詳細(官網提供的例子的jdk 為1.4的版本 匯入後需要修改一下)
官網提供的例子程式比較簡單與小巧 整個程式也就一百多k,但demo程式對於各種功能的使用講的非常詳細。
專案包結構分為三層:
- ZIP:該包下主要講述壓縮包的新增,修改,刪除等例子(包含加密檔案建立,通過流的方式建立 、新增壓縮檔案 、建立分卷壓縮檔案);
- MISC:該包下主要展示幾個工具方法例子,如:是否是分卷壓縮包的判斷、獲取壓縮包中的檔案資訊(檔名 大小等資訊)、壓縮排度檢視、根據檔名刪除壓縮包對應檔案等;
- EXTRACT:該包下例子都是關於解壓壓縮包的例子,包括解壓加密檔案等;
示例程式碼:
示例程式碼中需要對檔案進行操作,為方便程式執行建立以下三個檔案 可以直接執行大多數程式碼
- sample.txt
- myvideo.avi
- mysong.mp3
示例1 建立壓縮包添 加檔案到壓縮包中(未設定加密)
?123456789101112131415161718192021222324252627282930 | public class AddFilesDeflateComp { public AddFilesDeflateComp() { try { ZipFile zipFile = new ZipFile( "c:\\ZipTest\\AddFilesDeflateComp.zip" ); ArrayList<File> filesToAdd = new ArrayList<File>(); filesToAdd.add( new File( "c:\\ZipTest\\sample.txt" )); filesToAdd.add( new File( "c:\\ZipTest\\myvideo.avi" )); filesToAdd.add( new File( "c:\\ZipTest\\mysong.mp3" )); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to deflate compression parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); zipFile.addFiles(filesToAdd, parameters); } catch (ZipException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { new AddFilesDeflateComp(); } } |
- 該類主要用於建立普通壓縮包。如果壓縮包不存在 則會自動建立一個ZIP包;如果已經存在一個不為空的同名ZIP壓縮包 會將內容新增到該同名壓縮包中。
- 如果手動建立一個格式為ZIP的空壓縮包進行儲存,則為丟擲異常:ZipException :Negative seek offset
- 如果將其他的檔案字尾修改為ZIP包再執行程式,也會丟擲異常:ZipException: zip headers not found. probably not a zip file
- ZIP4J 提供ZipParameters物件來進行壓縮引數設定,其中setCompressionMethod方法可以設定壓縮還是 不壓縮
示例2 建立壓縮包新增檔案到 指定目錄中進行壓縮
?123456789101112131415161718192021222324252627282930313233 | public class AddFilesToFolderInZip { public AddFilesToFolderInZip() { try { ZipFile zipFile = new ZipFile( "c:\\ZipTest\\AddFilesDeflateComp.zip" ); ArrayList<File> filesToAdd = new ArrayList<File>(); filesToAdd.add( new File( "c:\\ZipTest\\sample.txt" )); filesToAdd.add( new File( "c:\\ZipTest\\myvideo.avi" )); filesToAdd.add( new File( "c:\\ZipTest\\mysong.mp3" )); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); parameters.setRootFolderInZip( "test2/" ); zipFile.addFiles(filesToAdd, parameters); } catch (ZipException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { new AddFilesToFolderInZip(); } } |
- 該程式執行後,會將sample.txt、myvideo.avi、mysong.mp3 新增到test2資料夾中 並生成AddFilesDeflateComp.zip 壓縮包
- 如果已經存在AddFilesDeflateComp.zip,則會將需要打包的內容新增到已經存在的壓縮包去
示例3 新增資料夾到壓縮包中
?12345678910111213141516171819202122232425 | public class AddFolder { public AddFolder() { try { ZipFile zipFile = new ZipFile( "c:\\ZipTest\\AddFolder.zip" ); String folderToAdd = "c:\\FolderToAdd" ; ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); zipFile.addFolder(folderToAdd, parameters); } catch (ZipException e) { e.printStackTrace(); } } public static void main(String[] args) { new AddFolder(); } } |
- 需要新增的資料夾必須存在,否則丟擲異常:ZipException: input folder does not exist
- * 如果已經存在同名檔案則會出現一個檔案的時候會出現一個問題,程式會生成一個臨時包並去修改之前存在的同名壓縮檔案,最後修改不成功且會丟擲異常:ZipException: cannot rename modified zip file最後只留下一個臨時包, 建議在生成的時候新增判斷 避免出現這種錯誤
示例4 建立加密壓縮包
?1234567891011121314151617181920212223242526272829303132333435 | public class AddFilesWithAESEncryption { public AddFilesWithAESEncryption() { try { ZipFile zipFile = new ZipFile( "c:\\ZipTest\\AddFilesWithAESZipEncryption.zip" ); ArrayList<File> filesToAdd = new ArrayList<File>(); filesToAdd.add( new File( "c:\\ZipTest\\sample.txt" )); filesToAdd.add( new File( "c:\\ZipTest\\myvideo.avi" )); filesToAdd.add( new File( "c:\\ZipTest\\mysong.mp3" )); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); parameters.setEncryptFiles( true ); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); parameters.setPassword( "123" ); zipFile.addFiles(filesToAdd, parameters); } catch (ZipException e) { e.printStackTrace(); } } public static void main(String[] args) { new AddFilesWithAESEncryption(); } } |
加密壓縮包後開啟時需要輸入密碼,與rar相同:
示例5 建立分卷壓縮包
?123456789101112131415161718192021222324252627282930313233 | public class CreateSplitZipFile { public CreateSplitZipFile() { try { ZipFile zipFile = new ZipFile( "c:\\ZipTest\\CreateSplitZipFile.zip" ); ArrayList<File> filesToAdd = new ArrayList<File>(); filesToAdd.add( new File( "c:\\ZipTest\\sample.txt" )); filesToAdd.add( new File( "c:\\ZipTest\\myvideo.avi" )); filesToAdd.add( new File( "c:\\ZipTest\\mysong.mp3" )); ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); zipFile.createZipFile(filesToAdd, parameters, true , 65536 ); } catch (ZipException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { new CreateSplitZipFile(); } } |
- 執行程式後會根據設定大小生成多個 壓縮包名.z + 數量編號檔案,如下圖:
- 如果已經存在同名壓縮包,則會丟擲異常提示已經存在:ZipException: zip file: c:\ZipTest\CreateSplitZipFile.zip already exists. To add files to existing zip file use addFile method
- 需要進行分卷壓縮的大小,不能小於規定的65536 bytes
示例6 通過流的方式新增檔案到壓縮包中
?123456789101112 |