Java解壓縮ZIP檔案
阿新 • • 發佈:2019-02-05
我們需要用到第三方的jar包:winszipaes_zh_CN_supported_20120416.jar
下載地址:
http://pan.baidu.com/s/1hqfi5Pa
這個包還依賴org.apache.commons.io.jar包。
下載地址:
http://pan.baidu.com/s/1eQuLDXg
至於使用方式,只要看一下DecryptionZipUtil.java就會了。
package com.ninemax.demo.zip.decrypt.zh_cn; import java.io.File; import java.io.IOException; import java.util.List; import java.util.zip.DataFormatException; import org.apache.commons.io.FileUtils; import de.idyl.winzipaes.AesZipFileDecrypter; import de.idyl.winzipaes.AesZipFileEncrypter; import de.idyl.winzipaes.impl.AESDecrypter; import de.idyl.winzipaes.impl.AESDecrypterBC; import de.idyl.winzipaes.impl.AESEncrypter; import de.idyl.winzipaes.impl.AESEncrypterBC; import de.idyl.winzipaes.impl.ExtZipEntry; /** * 壓縮指定檔案或目錄為ZIP格式壓縮檔案 * 支援中文(修改原始碼後) * 支援密碼(僅支援256bit的AES加密解密) * 依賴bcprov專案(bcprov-jdk16-140.jar) * * @author zyh */ public class DecryptionZipUtil { /** * 使用指定密碼將給定檔案或資料夾壓縮成指定的輸出ZIP檔案 * @param srcFile 需要壓縮的檔案或資料夾 * @param destPath 輸出路徑 * @param passwd 壓縮檔案使用的密碼 */ public static void zip(String srcFile,String destPath,String passwd) { AESEncrypter encrypter = new AESEncrypterBC(); AesZipFileEncrypter zipFileEncrypter = null; try { zipFileEncrypter = new AesZipFileEncrypter(destPath, encrypter); /** * 此方法是修改原始碼後新增,用以支援中文檔名 */ zipFileEncrypter.setEncoding("utf8"); File sFile = new File(srcFile); /** * AesZipFileEncrypter提供了過載的新增Entry的方法,其中: * add(File f, String passwd) * 方法是將檔案直接新增進壓縮檔案 * * add(File f, String pathForEntry, String passwd) * 方法是按指定路徑將檔案新增進壓縮檔案 * pathForEntry - to be used for addition of the file (path within zip file) */ doZip(sFile, zipFileEncrypter, "", passwd); } catch (IOException e) { e.printStackTrace(); } finally { try { zipFileEncrypter.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 具體壓縮方法,將給定檔案新增進壓縮檔案中,並處理壓縮檔案中的路徑 * @param file 給定磁碟檔案(是檔案直接新增,是目錄遞迴呼叫新增) * @param encrypter AesZipFileEncrypter例項,用於輸出加密ZIP檔案 * @param pathForEntry ZIP檔案中的路徑 * @param passwd 壓縮密碼 * @throws IOException */ private static void doZip(File file, AesZipFileEncrypter encrypter, String pathForEntry, String passwd) throws IOException { if (file.isFile()) { pathForEntry += file.getName(); encrypter.add(file, pathForEntry, passwd); return; } pathForEntry += file.getName() + File.separator; for(File subFile : file.listFiles()) { doZip(subFile, encrypter, pathForEntry, passwd); } } /** * 使用給定密碼解壓指定壓縮檔案到指定目錄 * @param inFile 指定Zip檔案 * @param outDir 解壓目錄 * @param passwd 解壓密碼 */ public static void unzip(String inFile, String outDir, String passwd) { File outDirectory = new File(outDir); if (!outDirectory.exists()) { outDirectory.mkdir(); } AESDecrypter decrypter = new AESDecrypterBC(); AesZipFileDecrypter zipDecrypter = null; try { zipDecrypter = new AesZipFileDecrypter(new File(inFile), decrypter); AesZipFileDecrypter.charset = "utf-8"; /** * 得到ZIP檔案中所有Entry,但此處好像與JDK裡不同,目錄不視為Entry * 需要建立資料夾,entry.isDirectory()方法同樣不適用,不知道是不是自己使用錯誤 * 處理資料夾問題處理可能不太好 */ List<ExtZipEntry> entryList = zipDecrypter.getEntryList(); for(ExtZipEntry entry : entryList) { String eName = entry.getName(); String dir = eName.substring(0, eName.lastIndexOf(File.separator) + 1); File extractDir = new File(outDir, dir); if (!extractDir.exists()) { FileUtils.forceMkdir(extractDir); } /** * 抽出檔案 */ File extractFile = new File(outDir + File.separator + eName); zipDecrypter.extractEntry(entry, extractFile, passwd); } } catch (IOException e) { e.printStackTrace(); } catch (DataFormatException e) { e.printStackTrace(); } finally { try { zipDecrypter.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 測試 * @param args */ public static void main(String[] args) { /** * 壓縮測試 * 可以傳檔案或者目錄 */ // zip("M:\\ZIP\\test\\bb\\a\\t.txt", "M:\\ZIP\\test\\temp1.zip", "zyh"); // zip("M:\\ZIP\\test\\bb", "M:\\ZIP\\test\\temp2.zip", "zyh"); unzip("M:\\ZIP\\test\\temp2.zip", "M:\\ZIP\\test\\temp", "zyh"); } }