zip壓縮檔案處理方案(Zip4j壓縮和解壓)
https://blog.csdn.net/ditto_zhou/article/details/82977395
主要特性
- Create, Add, Extract, Update, Remove files from a Zip file針對ZIP壓縮檔案建立、新增、抽出、更新和移除檔案
- Read/Write password protected Zip files(讀寫有密碼保護的Zip檔案)
- Supports AES 128/256 Encryption(支援AES 128/256演算法加密)
- Supports Standard Zip Encryption(支援標準Zip演算法加密)
- Supports Zip64 format(支援zip64格式)
- Supports Store (No Compression) and Deflate compression method(支援Store(非壓縮)和Deflate壓縮方法---不太明白)
- Create or extract files from Split Zip files (Ex: z01, z02,...zip)(針對分塊zip檔案建立和抽出檔案)
- Supports Unicode file names(支援Unicode編碼檔名)Progress Monitor(進度監控)
使用
zip4j預設採用utf-8編碼,支援中文,也支援密碼和多種壓縮演算法,可以說是功能強大,只是簡單的解壓檔案,按照下面幾步
public static void upzip(File zipFile,String dest,String password) {
try {
ZipFile zFile = new ZipFile(zipFile);//指向壓縮檔案.zip
//設定檔名編碼,在gbk系統中需要設定,檔名稱是中文就不會亂碼
zFile.setFileNameCharset("gbk");
if(!zFile.isValidZipFile()) {// 檢查檔案是否合法
throw new Exception("檔名不合法");
}
File destFile = new File(dest);//解壓目錄
if(destFile.isDirectory()&&!destFile.exists()) {
destFile.mkdirs();
}
if(zFile.isEncrypted()) {//如果設定了密碼
zFile.setPassword(password.toCharArray());
}
zFile.extractAll(dest);//將檔案輸出到目標目錄
} catch (Exception e) {
e.printStackTrace();
}
}
注意,如果解壓的檔案中檔名包含中文,一定要設定檔名字符集編碼
zFile.setFileNameCharset("gbk");
對檔名編碼字符集方法的呼叫一定要靠前,必須在isValidZipFile方法前呼叫,因為isValidZipFile方法的呼叫,會去設定檔名的編碼
zFile.isValidZipFile()
zipModel = headerReader.readAllHeaders(this.fileNameCharset);
壓縮和解壓
public class CompressUtil {
private static Logger logger = Logger.getLogger(CompressUtil.class);
/**
* 解壓檔案
*
* @param zipFile 壓縮檔案
* @param dest 解壓檔案的存放目錄
* @param password 壓縮檔案的密碼
*/
public static void unzip(File zipFile, String dest, String password) {
try {
ZipFile zFile = new ZipFile(zipFile);// 指向壓縮檔案.zip
zFile.setFileNameCharset("gbk");// 設定檔名編碼,在gbk系統中需要設定
if (!zFile.isValidZipFile()) {// 檢查檔案是否合法
throw new Exception("檔名不合法");
}
File destFile = new File(dest);// 解壓目錄
if (destFile.isDirectory() && !destFile.exists()) {
destFile.mkdirs();
}
if (zFile.isEncrypted()) {// 如果設定了密碼
zFile.setPassword(password.toCharArray());
}
zFile.extractAll(dest);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 返回的是解壓後的檔案陣列
*
* @param zipFile 壓縮檔案路徑
* @param desc 解壓後檔案的存放路徑
* @param passwd 密碼
* @param charset 檔名稱編碼
* @return
*/
public static File[] getFilesByUnzip(File zipFile, String dest, String passwd, String charset) {
try {
ZipFile zFile = new ZipFile(zipFile);
zFile.setFileNameCharset(charset);
if (!zFile.isValidZipFile()) {
throw new Exception("檔名稱不合法");
}
File destFile = new File(dest);
if (destFile.isDirectory() && !destFile.exists()) {
destFile.mkdirs();
}
if (zFile.isEncrypted()) {
zFile.setPassword(passwd);
}
zFile.extractAll(dest);
// 獲取檔案列表
List fileHeaders = zFile.getFileHeaders();
List<File> extractFiles = new ArrayList<>();
if (fileHeaders != null && fileHeaders.size() > 0) {
for (int i = 0; i < fileHeaders.size(); i++) {
FileHeader header = (FileHeader) fileHeaders.get(i);
if (header != null) {
extractFiles.add(new File(destFile, header.getFileName()));
}
}
}
File[] arr = new File[extractFiles.size()];
return extractFiles.toArray(arr);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使用給定密碼壓縮指定檔案或資料夾到指定位置. dest可傳最終壓縮檔案存放的絕對路徑,也可以傳存放目錄,也可以傳null或者"".
* 如果傳null或者""則將壓縮檔案存放在當前目錄,即跟原始檔同目錄,壓縮檔名取原始檔名,以.zip為字尾;
* 如果以路徑分隔符(File.separator)結尾,則視為目錄,壓縮檔名取原始檔名,以.zip為字尾,否則視為檔名.
* @param src 要壓縮的檔案或資料夾路徑
* @param dest 壓縮檔案存放路徑
* @param isCreateDir 是否在壓縮檔案裡建立目錄,僅在壓縮檔案為目錄時有效. 如果為false,將直接壓縮目錄下檔案到壓縮檔案.
* @param passwd 壓縮使用的密碼
* @return 最終的壓縮檔案存放的絕對路徑,如果為null則說明壓縮失敗.
*/
public static String zip(String src, String dest, boolean isCreateDir, String passwd) {
File srcFile = new File(src);
dest = buildDestinationZipFilePath(srcFile, dest);//獲取壓縮檔案的存放路徑
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);//設定壓縮方法是deflate
zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);//設定壓縮級別
if(passwd!=null&&passwd.trim().length()>0) {
// 如果密碼不為空,壓縮包進行加密,需要設定壓縮演算法
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);//加密演算法設定為standard
zipParameters.setPassword(passwd.toCharArray());
}
try {
ZipFile zipFile = new ZipFile(dest);
if(srcFile.isDirectory()) {
if(!isCreateDir) {//如果false,表示不按照目錄結構進行壓縮
ArrayList<File> list = new ArrayList<>();
Collections.addAll(list, srcFile.listFiles());
zipFile.addFiles(list, zipParameters);
}else {
//按照目錄結構壓縮
zipFile.addFolder(srcFile, zipParameters);
}
}else {
zipFile.addFile(srcFile, zipParameters);
}
} catch (ZipException e) {
logger.error("-----檔案壓縮失敗-----");
logger.error(e.getMessage());
dest = null;
}
return dest;
}
/**
* 構建壓縮檔案存放路徑,如果不存在將會建立 * 傳入的可能是檔名或者目錄,也可能不傳,此方法用以轉換最終壓縮檔案的存放路徑 *
* @param srcFile 原始檔
* @param destParam 壓縮目標路徑 *
* @return 正確的壓縮檔案存放路徑
*/
private static String buildDestinationZipFilePath(File srcFile, String destParam) {
if (destParam == null || destParam.trim() == "") {
if (srcFile.isDirectory()) {
destParam = srcFile.getParent() + File.separator + srcFile.getName() + ".zip";
} else {
String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));
destParam = srcFile.getParent() + File.separator + fileName + ".zip";
}
} else {
createDestDirectoryIfNecessary(destParam); // 在指定路徑不存在的情況下將其建立出來
if (destParam.endsWith(File.separator)) {
String fileName = "";
if (srcFile.isDirectory()) {
fileName = srcFile.getName();
} else {
fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));
}
destParam += fileName + ".zip";
}
}
return destParam;
}
/**
* 建立壓縮檔案存放目錄
* @param destParam
*/
private static void createDestDirectoryIfNecessary(String destParam) {
File file = null;
if(destParam.endsWith(File.separator)) {
file = new File(destParam);
}else {
file = new File(destParam.substring(0, destParam.lastIndexOf(File.separator)));
}
if(file.exists()) {
file.mkdirs();
}
}
}
刪除
進行刪除操作前, 也要設定檔名編碼為gbk,因為如果是中文名稱的檔案,就會丟擲could not find file header for file的錯誤
刪除檔案
根據檔名稱或者FileHeader刪除
public RemoveFileFromZipFile() {
try {
// Initiate ZipFile object with the path/name of the zip file.
ZipFile zipFile = new ZipFile("d:\\1.zip");
zipFile.setFileNameCharset("gbk");
// Note: If this zip file is a split file then this method throws an exception as
// Zip Format Specification does not allow updating split zip files
// Please make sure that this zip file has more than one file to completely test
// this example
// Removal of a file from a zip file can be done in two ways:
// 1. 直接根據檔名稱刪除
zipFile.removeFile("新建文字文件.txt");
// 2. 建立FileHeader,根據FileHeader刪除
if (zipFile.getFileHeaders() != null && zipFile.getFileHeaders().size() > 0) {
zipFile.removeFile((FileHeader)zipFile.getFileHeaders().get(0));
} else {
System.out.println("This cannot be demonstrated as zip file does not have any files left");
}
} catch (ZipException e) {
e.printStackTrace();
}
刪除目錄
將目錄下面的檔案刪除,在刪除目錄
/**
* 刪除壓縮檔案中的檔案或者目錄
* @param file 壓縮檔案的路徑
* @param removeFile 檔名或者目錄
*/
public static void removeDirFromZip(String file,String removeFile) {
try {
ZipFile zipFile = new ZipFile(file);
zipFile.setFileNameCharset("gbk");//設定檔名的編碼格式
if(!removeFile.endsWith("/")) {
//刪除檔案的方式,第一種是根據檔案的名稱,第二種是根據檔案的fileHeader進行刪除
//zipFile.removeFile(removeFile);
FileHeader header = new FileHeader();
header.setFileName(removeFile);
zipFile.removeFile(header);
}else {
//如果是目錄的話,需要先將目錄下面的檔案刪除掉,在刪除目錄
if(!removeFile.endsWith("/")) removeFile +="/";
List headers = zipFile.getFileHeaders();
List<FileHeader> removeFiles = new ArrayList<>();
for (int i = 0; i < headers.size(); i++) {
FileHeader subHeader =(FileHeader) headers.get(i);
if(subHeader.getFileName().contains(removeFile)
&&!subHeader.getFileName().equals(removeFile)) {
//不能直接刪除,會丟擲java.lang.IndexOutOfBoundsException
// zipFile.removeFile(subHeader);
// 這裡我們使用一個list記錄下刪除的subheader,在進行刪除
removeFiles.add(subHeader);
}
}
for (int i = 0; i < removeFiles.size(); i++) {
zipFile.removeFile(removeFiles.get(i));
}
//最後將目錄刪除
if(zipFile.getFileHeader(removeFile)!=null) {
zipFile.removeFile(removeFile);
}
}
} catch (ZipException e) {
e.printStackTrace();
}
}
參考部落格:https://blog.csdn.net/zhyh1986/article/details/7921376
相關文章
- zip壓縮和解壓縮
- 檔案壓縮和解壓縮
- 簡單的zip壓縮和解壓縮
- Linux中檔案的壓縮和解壓縮Linux
- JAVA壓縮和解壓縮Java
- linux檔案壓縮和解壓命令Linux
- linux下的檔案的壓縮和解壓縮Linux
- 字串的壓縮和解壓縮字串
- node ~ zip壓縮 && 檔案加密加密
- ZipArchive解壓縮zip檔案Hive
- 批處理 壓縮zip 並過濾部分檔案
- 使用org.apache.tools.zip實現zip壓縮和解壓Apache
- linux壓縮和解壓縮命令Linux
- pclzip壓縮檔案和解壓的多種示例
- C# 壓縮和解壓檔案(SharpZipLib)C#
- java中 檔案壓縮處理Java
- Linux科研武器庫 - 檔案壓縮與解壓縮 - zip / unzipLinux
- java 把檔案壓縮成 zipJava
- java 生成 zip格式 壓縮檔案Java
- linux壓縮和解壓縮命令整理Linux
- linux壓縮和解壓縮命令大全Linux
- Python實現壓縮和解壓縮Python
- 壓縮解壓命令(tar, zip)
- zip解壓縮
- Linux tar壓縮和解壓縮等命令Linux
- 使用jar與zip壓縮解壓檔案的區別JAR
- 利用Java實現zip壓縮/解壓縮 (轉)Java
- aix 檔案的壓縮與解壓縮AI
- .NET 壓縮/解壓檔案
- 批處理壓縮
- Java使用Zip壓縮Java
- Java實現檔案壓縮與解壓[zip格式,gzip格式]Java
- 【Linux基礎】壓縮和解壓Linux
- 常用的壓縮和解壓命令案例
- 壓縮檔案格式rar和zip有什麼區別 壓縮檔案格式rar和zip哪個好
- SpringBoot-檔案壓縮處理Spring Boot
- CentOS中zip壓縮和unzip解壓縮命令詳解CentOS
- 分卷壓縮怎麼解壓 快速解壓電腦分卷壓縮檔案方法