ZIP4J---ZIP文件壓縮與解壓縮學習

          最近公司準備讓各項目組提供公共工具組件,手中正好無事便研究其中一個工具 - 文件壓縮與解壓縮工具。 java

          目前JAVA API已提供對於ZIP文件的壓縮與解壓縮,但網上總結不支持ZIP文件加密與解密甚至對於中文支持也有問題,因而果斷找其餘的支持加密解密的第三方包。 winzipaes 與 ZIP4J 都符合項目的要求 ,最終選擇ZIP4J來進行使用。 算法

  • ZIP4J 是一個支持處理ZIP文件的開源庫
  • 支持建立,修改,添加,刪除,解壓 壓縮文件
  • 支持讀/寫密碼保護
  • 支持AES加密 128/256
  • 支持標準ZIP加密
  • 支持進度監視器
  • 自持Unicode 文件名
  • 支持建立分卷壓縮文件
  • 支持將文件添加到壓縮包中但不進行壓縮


ZIP4J 項目地址爲  :http://www.lingala.net/zip4j/ ,但該地址沒法直接訪問須要使用代理進行訪問 ide

再提供一個在線代理網站:http://www.7daili.com/ 工具

目前ZIP4J 版本爲:1.3.1 ,只須要直接下一載一個zip4j_1.3.1.jar一個jar包便可,同時能夠下載官網提供的例子進行學習,例子至關詳細(官網提供的例子的jdk 爲1.4的版本 導入後須要修改一下 學習




官網提供的例子程序比較簡單與小巧 整個程序也就一百多k,但demo程序對於各類功能的使用講的很是詳細。 測試

項目包結構分爲三層: 網站

  • ZIP:該包下主要講述壓縮包的新增,修改,刪除等例子(包含加密文件建立,經過流的方式建立 、添加壓縮文件 、建立分卷壓縮文件);
  • MISC:該包下主要展現幾個工具方法例子,如:是不是分卷壓縮包的判斷、獲取壓縮包中的文件信息(文件名 大小等信息)、壓縮進度查看、根據文件名刪除壓縮包對應文件等;
  • EXTRACT:該包下例子都是關於解壓壓縮包的例子,包括解壓加密文件等;


示例代碼加密

示例代碼中須要對文件進行操做,爲方便程序運行建立如下三個文件 能夠直接運行大多數代碼 spa

  1. sample.txt
  2. myvideo.avi
  3. mysong.mp3


示例1 建立壓縮包添 加文件到壓縮包中(未設置加密) .net

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 建立壓縮包添加文件到 指定目錄中進行壓縮

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 添加文件夾到壓縮包中

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 建立加密壓縮包

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 建立分卷壓縮包

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 經過流的方式添加文件到壓縮包中

public class AddStreamToZip {
	
	public AddStreamToZip() {
		
		InputStream is = null;
		
		try {
			ZipFile zipFile = new ZipFile("c:\\ZipTest\\AddStreamToZip.zip");

			ZipParameters parameters = new ZipParameters();
			parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
			parameters.setFileNameInZip("yourfilename.txt");
			parameters.setSourceExternalStream(true);
			
			is = new FileInputStream("c:\\ZipTest\\sample.txt");
			zipFile.addStream(is, parameters);
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		new AddStreamToZip();
		
	}
	
	
}


示例7 解壓壓縮文件

public class ExtractAllFiles {
	
	public ExtractAllFiles() {
		
		try {
			ZipFile zipFile = new ZipFile("c:\\ZipTest\\ProgressInformation.zip");
			zipFile.extractAll("c:\\ZipTest1");
			
		} catch (ZipException e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ExtractAllFiles();
	}

}
  • 若是解壓的文件須要密碼,能夠添加如下代碼:
  • if (zipFile.isEncrypted()) {
    				// if yes, then set the password for the zip file
    				zipFile.setPassword("test123!");
    			}

  • 在進行解壓縮時須要判斷文件是否爲加密壓縮,不然會拋出異常:ZipException: empty or null password provided for AES Decryptor

壓縮效率

   ZIP4J提供5中壓縮算法:

  1.     DEFLATE_LEVEL_FASTEST 
  2.     DEFLATE_LEVEL_FASTEST
  3.     DEFLATE_LEVEL_NORMAL
  4.     DEFLATE_LEVEL_MAXIMUM
  5.     DEFLATE_LEVEL_ULTRA

   根據API提供的幾種不一樣壓縮級別進行測試(文件夾壓縮),測試結果以下:

   一個180M的文件夾壓縮後

  •    WinRAR 30秒 - 78.7 MB ; 
  •    NORMAL - 18 秒 91.2 MB  ;
  •    FAST 13秒 -93.1 MB;
  •    FASTEST - 最快速10 秒94.7 MB 
  •    MAXIMUM 23 秒 - 90.7 MB;
  •    ULTRA -50 90.6 MB

    與WinRAR 相比較來講,壓縮時間仍是很不錯 但對文件的壓縮大小來講仍是WINRAR要強一些 (各人電腦配置不一樣 壓縮的時間這些也不一樣)


     以上即是ZIP4J提供的一些經常使用的工具方法,總結在此,方便本身與你們使用。若是有更好的工具或者有不正確的地方歡迎你們指出!

相關文章
相關標籤/搜索