日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

zip4j -- Java处理zip压缩文件

發(fā)布時間:2025/3/15 java 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 zip4j -- Java处理zip压缩文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?ZIP4J,作為解決了我的問題的終極解決方案,本來一開始在搜索引擎上就看到了它的蹤跡,但因天朝的網絡環(huán)境問題,zip4j的官網一直無法訪問,最終使我多走了好多冤枉路,期間試過JDK的zip包,試過Apache的zip解決方案,也試過如winzipaes等其它的開源框架,最終沒有滿足自己的需求,最后,我不得已掛了一下代理將zip4j下載了下來,試用了一下,果然威力無比,所到之處所向披靡...

閑話少說,如果需要可以到zip4j的官網下載該開源項目:

http://www.lingala.net/zip4j/

不過需要提醒的是可能無法直接訪問,如果無法正常訪問,請自行準備代理訪問,如果各位嫌麻煩,可以到這里下載:

http://download.csdn.net/detail/number_chc/7751199


ZIP4J的官方說明


(自己翻譯了一下,英文不好,呵呵...)

Key features(主要特性):

  • Create, Add, Extract, Update, Remove files from a Zip file
    針對ZIP壓縮文件創(chuàng)建、添加、抽出、更新和移除文件
  • 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文件創(chuàng)建和抽出文件)
  • Supports Unicode file names
    (支持Unicode編碼文件名)
  • Progress Monitor
    (進度監(jiān)控)

從上面的主要特性可以看出,zip4j的功能是非常強大的,完全可以利用其寫個類似于好壓的zip文件管理軟件,但我們用地最多的可能還是利用其作一些簡單的解壓和壓縮操作,其它的功能極少觸碰,我也一樣,呵呵...


使用注意點


zip4j默認采用UTF-8編碼,所以它支持中文,同時也支持密碼,而且支持多種壓縮算法,可以說功能強大,但使用起來卻非常簡單,當然,如果需求比較復雜,那就得好好去研究了。如果你僅僅是簡單地解壓一個zip壓縮文件,那么只需要簡單地幾步即可:

[java] view plaincopy
  • public?static?void?unzip(File?zipFile,?String?dest,?String?passwd)?throws?ZipException?{????
  • ????????ZipFile?zFile?=?new?ZipFile(zipFile);??//?首先創(chuàng)建ZipFile指向磁盤上的.zip文件????
  • ????????zFile.setFileNameCharset("GBK");???????//?設置文件名編碼,在GBK系統中需要設置????
  • ????????if?(!zFile.isValidZipFile())?{???//?驗證.zip文件是否合法,包括文件是否存在、是否為zip文件、是否被損壞等????
  • ????????????throw?new?ZipException("壓縮文件不合法,可能被損壞.");????
  • ????????}????
  • ????????File?destDir?=?new?File(dest);?????//?解壓目錄????
  • ????????if?(destDir.isDirectory()?&&?!destDir.exists())?{????
  • ????????????destDir.mkdir();????
  • ????????}????
  • ????????if?(zFile.isEncrypted())?{????
  • ????????????zFile.setPassword(passwd.toCharArray());??//?設置密碼????
  • ????????}????
  • ????????zFile.extractAll(dest);??????//?將文件抽出到解壓目錄(解壓)????
  • ????}????
  • ?當然將指定文件壓縮成zip文件也是非常簡單的事,此處不再貼代碼,如有需要請參看下面的完整示例。

    ?提示:如果將要解壓的壓縮文件中的文件名含有中文,解壓時需要注意一點,就是設置文件名字符集方法

    [java] view plaincopy
  • zFile.setFileNameCharset("GBK");???
  • 這個方法的調用一定要靠前,要靠多前呢?其實最好在創(chuàng)建ZipFile之后就設置上,至少要在

    [java] view plaincopy
  • zFile.isValidZipFile()????
  • 這個方法調用之前調用,我在應用時因為這個問題耽誤好久,最后查看源碼才弄明白,好像是ZipFile在驗證方法中就將編碼設置好,以后就不再對文件名編碼作改變了。


    完整示例


    下面提供一個自己寫的例子,鄙人才疏學淺,天分也差,寫的代碼質量很差,斗膽貼上,希望能起到拋磚引玉的作用。

    [java] view plaincopy
  • package?com.ninemax.cul.util;??
  • ??
  • import?java.io.File;??
  • import?java.util.ArrayList;??
  • import?java.util.Collections;??
  • import?java.util.List;??
  • ??
  • import?org.apache.commons.lang3.StringUtils;??
  • ??
  • import?net.lingala.zip4j.core.ZipFile;??
  • import?net.lingala.zip4j.exception.ZipException;??
  • import?net.lingala.zip4j.model.FileHeader;??
  • import?net.lingala.zip4j.model.ZipParameters;??
  • import?net.lingala.zip4j.util.Zip4jConstants;??
  • ??
  • /**?
  • ?*?ZIP壓縮文件操作工具類?
  • ?*?支持密碼?
  • ?*?依賴zip4j開源項目(http://www.lingala.net/zip4j/)?
  • ?*?版本1.3.1?
  • ?*?@author?ninemax?
  • ?*/??
  • public?class?CompressUtil?{??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼解壓指定的ZIP壓縮文件到指定目錄?
  • ?????*?<p>?
  • ?????*?如果指定目錄不存在,可以自動創(chuàng)建,不合法的路徑將導致異常被拋出?
  • ?????*?@param?zip?指定的ZIP壓縮文件?
  • ?????*?@param?dest?解壓目錄?
  • ?????*?@param?passwd?ZIP文件的密碼?
  • ?????*?@return?解壓后文件數組?
  • ?????*?@throws?ZipException?壓縮文件有損壞或者解壓縮失敗拋出?
  • ?????*/??
  • ????public?static?File?[]?unzip(String?zip,?String?dest,?String?passwd)?throws?ZipException?{??
  • ????????File?zipFile?=?new?File(zip);??
  • ????????return?unzip(zipFile,?dest,?passwd);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼解壓指定的ZIP壓縮文件到當前目錄?
  • ?????*?@param?zip?指定的ZIP壓縮文件?
  • ?????*?@param?passwd?ZIP文件的密碼?
  • ?????*?@return??解壓后文件數組?
  • ?????*?@throws?ZipException?壓縮文件有損壞或者解壓縮失敗拋出?
  • ?????*/??
  • ????public?static?File?[]?unzip(String?zip,?String?passwd)?throws?ZipException?{??
  • ????????File?zipFile?=?new?File(zip);??
  • ????????File?parentDir?=?zipFile.getParentFile();??
  • ????????return?unzip(zipFile,?parentDir.getAbsolutePath(),?passwd);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼解壓指定的ZIP壓縮文件到指定目錄?
  • ?????*?<p>?
  • ?????*?如果指定目錄不存在,可以自動創(chuàng)建,不合法的路徑將導致異常被拋出?
  • ?????*?@param?zip?指定的ZIP壓縮文件?
  • ?????*?@param?dest?解壓目錄?
  • ?????*?@param?passwd?ZIP文件的密碼?
  • ?????*?@return??解壓后文件數組?
  • ?????*?@throws?ZipException?壓縮文件有損壞或者解壓縮失敗拋出?
  • ?????*/??
  • ????public?static?File?[]?unzip(File?zipFile,?String?dest,?String?passwd)?throws?ZipException?{??
  • ????????ZipFile?zFile?=?new?ZipFile(zipFile);??
  • ????????zFile.setFileNameCharset("GBK");??
  • ????????if?(!zFile.isValidZipFile())?{??
  • ????????????throw?new?ZipException("壓縮文件不合法,可能被損壞.");??
  • ????????}??
  • ????????File?destDir?=?new?File(dest);??
  • ????????if?(destDir.isDirectory()?&&?!destDir.exists())?{??
  • ????????????destDir.mkdir();??
  • ????????}??
  • ????????if?(zFile.isEncrypted())?{??
  • ????????????zFile.setPassword(passwd.toCharArray());??
  • ????????}??
  • ????????zFile.extractAll(dest);??
  • ??????????
  • ????????List<FileHeader>?headerList?=?zFile.getFileHeaders();??
  • ????????List<File>?extractedFileList?=?new?ArrayList<File>();??
  • ????????for(FileHeader?fileHeader?:?headerList)?{??
  • ????????????if?(!fileHeader.isDirectory())?{??
  • ????????????????extractedFileList.add(new?File(destDir,fileHeader.getFileName()));??
  • ????????????}??
  • ????????}??
  • ????????File?[]?extractedFiles?=?new?File[extractedFileList.size()];??
  • ????????extractedFileList.toArray(extractedFiles);??
  • ????????return?extractedFiles;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?壓縮指定文件到當前文件夾?
  • ?????*?@param?src?要壓縮的指定文件?
  • ?????*?@return?最終的壓縮文件存放的絕對路徑,如果為null則說明壓縮失敗.?
  • ?????*/??
  • ????public?static?String?zip(String?src)?{??
  • ????????return?zip(src,null);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼壓縮指定文件或文件夾到當前目錄?
  • ?????*?@param?src?要壓縮的文件?
  • ?????*?@param?passwd?壓縮使用的密碼?
  • ?????*?@return?最終的壓縮文件存放的絕對路徑,如果為null則說明壓縮失敗.?
  • ?????*/??
  • ????public?static?String?zip(String?src,?String?passwd)?{??
  • ????????return?zip(src,?null,?passwd);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼壓縮指定文件或文件夾到當前目錄?
  • ?????*?@param?src?要壓縮的文件?
  • ?????*?@param?dest?壓縮文件存放路徑?
  • ?????*?@param?passwd?壓縮使用的密碼?
  • ?????*?@return?最終的壓縮文件存放的絕對路徑,如果為null則說明壓縮失敗.?
  • ?????*/??
  • ????public?static?String?zip(String?src,?String?dest,?String?passwd)?{??
  • ????????return?zip(src,?dest,?true,?passwd);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?使用給定密碼壓縮指定文件或文件夾到指定位置.?
  • ?????*?<p>?
  • ?????*?dest可傳最終壓縮文件存放的絕對路徑,也可以傳存放目錄,也可以傳null或者"".<br?/>?
  • ?????*?如果傳null或者""則將壓縮文件存放在當前目錄,即跟源文件同目錄,壓縮文件名取源文件名,以.zip為后綴;<br?/>?
  • ?????*?如果以路徑分隔符(File.separator)結尾,則視為目錄,壓縮文件名取源文件名,以.zip為后綴,否則視為文件名.?
  • ?????*?@param?src?要壓縮的文件或文件夾路徑?
  • ?????*?@param?dest?壓縮文件存放路徑?
  • ?????*?@param?isCreateDir?是否在壓縮文件里創(chuàng)建目錄,僅在壓縮文件為目錄時有效.<br?/>?
  • ?????*?如果為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?parameters?=?new?ZipParameters();??
  • ????????parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);???????????//?壓縮方式??
  • ????????parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);????//?壓縮級別??
  • ????????if?(!StringUtils.isEmpty(passwd))?{??
  • ????????????parameters.setEncryptFiles(true);??
  • ????????????parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);?//?加密方式??
  • ????????????parameters.setPassword(passwd.toCharArray());??
  • ????????}??
  • ????????try?{??
  • ????????????ZipFile?zipFile?=?new?ZipFile(dest);??
  • ????????????if?(srcFile.isDirectory())?{??
  • ????????????????//?如果不創(chuàng)建目錄的話,將直接把給定目錄下的文件壓縮到壓縮文件,即沒有目錄結構??
  • ????????????????if?(!isCreateDir)?{??
  • ????????????????????File?[]?subFiles?=?srcFile.listFiles();??
  • ????????????????????ArrayList<File>?temp?=?new?ArrayList<File>();??
  • ????????????????????Collections.addAll(temp,?subFiles);??
  • ????????????????????zipFile.addFiles(temp,?parameters);??
  • ????????????????????return?dest;??
  • ????????????????}??
  • ????????????????zipFile.addFolder(srcFile,?parameters);??
  • ????????????}?else?{??
  • ????????????????zipFile.addFile(srcFile,?parameters);??
  • ????????????}??
  • ????????????return?dest;??
  • ????????}?catch?(ZipException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????????return?null;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?構建壓縮文件存放路徑,如果不存在將會創(chuàng)建?
  • ?????*?傳入的可能是文件名或者目錄,也可能不傳,此方法用以轉換最終壓縮文件的存放路徑?
  • ?????*?@param?srcFile?源文件?
  • ?????*?@param?destParam?壓縮目標路徑?
  • ?????*?@return?正確的壓縮文件存放路徑?
  • ?????*/??
  • ????private?static?String?buildDestinationZipFilePath(File?srcFile,String?destParam)?{??
  • ????????if?(StringUtils.isEmpty(destParam))?{??
  • ????????????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);??//?在指定路徑不存在的情況下將其創(chuàng)建出來??
  • ????????????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;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?在必要的情況下創(chuàng)建壓縮文件存放目錄,比如指定的存放路徑并沒有被創(chuàng)建?
  • ?????*?@param?destParam?指定的存放路徑,有可能該路徑并沒有被創(chuàng)建?
  • ?????*/??
  • ????private?static?void?createDestDirectoryIfNecessary(String?destParam)?{??
  • ????????File?destDir?=?null;??
  • ????????if?(destParam.endsWith(File.separator))?{??
  • ????????????destDir?=?new?File(destParam);??
  • ????????}?else?{??
  • ????????????destDir?=?new?File(destParam.substring(0,?destParam.lastIndexOf(File.separator)));??
  • ????????}??
  • ????????if?(!destDir.exists())?{??
  • ????????????destDir.mkdirs();??
  • ????????}??
  • ????}??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????zip("d:\\test\\cc",?"d:\\test\\cc.zip",?"11");??
  • //??????try?{??
  • //??????????File[]?files?=?unzip("d:\\test\\漢字.zip",?"aa");??
  • //??????????for?(int?i?=?0;?i?<?files.length;?i++)?{??
  • //??????????????System.out.println(files[i]);??
  • //??????????}??
  • //??????}?catch?(ZipException?e)?{??
  • //??????????e.printStackTrace();??
  • //??????}??
  • ????}??
  • }??

  • 需要學習的東西太多,沒太多時間(或許只是借口)去研究它,上面的例子僅是簡單地解壓和壓縮操作;但在使用中可以發(fā)現Zip4J功能比較完備,如果需要更多地支持,那就真要好好去研究一下它,也許它真的不會使您失望。。。


    補充


    刪除壓縮文件中的目錄


    看到有朋友在問如何刪除壓縮文件中的目錄,在這里補充一下。

    利用zip4j刪除壓縮文件中的目錄,查閱API后很容易想到這樣的方式:

    [java] view plaincopy
  • ZipFile?zipFile?=?new?ZipFile("d:\\FeiQ-V2.5.zip");??
  • zipFile.setFileNameCharset("GBK");??
  • zipFile.removeFile("sounds/");??????//?sounds是zip文件中的一個目錄??

  • 但這種直接刪除壓縮文件中非空目錄的方式是不會成功的,你會看到zip文件絲毫沒有變化,雖然目錄對應的FileHeader已被刪除(表現就是如果這時再將目錄下的所有文件刪除,則該目錄隨之消失) ;因此我們需要將該目錄下所有的文件都刪除掉,最后再將目錄刪除,根據這個思路,我們很容易形成如下的代碼:

    [java] view plaincopy
  • void?removeDirFromZipArchive(String?file,?String?removeDir)?throws?ZipException?{??
  • ????//?創(chuàng)建ZipFile并設置編碼??
  • ????ZipFile?zipFile?=?new?ZipFile(file);??
  • ????zipFile.setFileNameCharset("GBK");??
  • ??????
  • ????//?給要刪除的目錄加上路徑分隔符??
  • ????if?(!removeDir.endsWith(File.separator))?removeDir?+=?File.separator;??
  • ??
  • ????//?如果目錄不存在,?直接返回??
  • ????FileHeader?dirHeader?=?zipFile.getFileHeader(removeDir);??
  • ????if?(null?==?dirHeader)?return;??
  • ??
  • ????//?遍歷壓縮文件中所有的FileHeader,?將指定刪除目錄下的子文件刪除??
  • ????List?allHeaders?=?zipFile.getFileHeaders();??
  • ????for(int?i=0,?len?=?allHeaders.size();?i<len;?i++)?{??
  • ????????FileHeader?subHeader?=?(FileHeader)?allHeaders.get(i);??
  • ????????if?(subHeader.getFileName().startsWith(dirHeader.getFileName())??
  • ????????????????&&?!subHeader.getFileName().equals(dirHeader.getFileName()))?{??
  • ????????????zipFile.removeFile(subHeader);??
  • ????????}??
  • ????}??
  • ????//?最后刪除指定目錄??
  • ????zipFile.removeFile(dirHeader);??
  • }??
  • 這樣仍然解決不了問題,如果你這樣做了,那么你將會得到一個java.lang.IndexOutOfBoundsException異常,那么看似正常的代碼為什么會報索引越界異常呢?其實我們通過zipFile.getFileHeaders()方法得到的List會隨遍歷中的刪除操作而發(fā)生變化,也就是說我們刪除了某個FileHeader,將會反映到該List中。每成功刪除一個FileHeader,List長度就減1,而i一直在0至List的初始長度之間遞增,反復幾次后就可能出現越界異常。

    為了避免這種情況發(fā)生,我們可以多做一些操作,比如可以在遍歷中暫不進行刪除操作,而只是將要刪除的文件記錄下來,遍歷結束后再統一刪除,最后將目錄刪除,經測試,這個思路可以解決問題。

    簡單示例代碼:

    [java] view plaincopy
  • void?removeDirFromZipArchive(String?file,?String?removeDir)?throws?ZipException?{??
  • ????//?創(chuàng)建ZipFile并設置編碼??
  • ????ZipFile?zipFile?=?new?ZipFile(file);??
  • ????zipFile.setFileNameCharset("GBK");??
  • ??????
  • ????//?給要刪除的目錄加上路徑分隔符??
  • ????if?(!removeDir.endsWith(File.separator))?removeDir?+=?File.separator;??
  • ??????
  • ????//?如果目錄不存在,?直接返回??
  • ????FileHeader?dirHeader?=?zipFile.getFileHeader(removeDir);??
  • ????if?(null?==?dirHeader)?return;??
  • ??
  • ????//?遍歷壓縮文件中所有的FileHeader,?將指定刪除目錄下的子文件名保存起來??
  • ????List?headersList?=?zipFile.getFileHeaders();??
  • ????List<String>?removeHeaderNames?=?new?ArrayList<String>();??
  • ????for(int?i=0,?len?=?headersList.size();?i<len;?i++)?{??
  • ????????FileHeader?subHeader?=?(FileHeader)?headersList.get(i);??
  • ????????if?(subHeader.getFileName().startsWith(dirHeader.getFileName())??
  • ????????????????&&?!subHeader.getFileName().equals(dirHeader.getFileName()))?{??
  • ????????????removeHeaderNames.add(subHeader.getFileName());??
  • ????????}??
  • ????}??
  • ????//?遍歷刪除指定目錄下的所有子文件,?最后刪除指定目錄(此時已為空目錄)??
  • ????for(String?headerNameString?:?removeHeaderNames)?{??
  • ????????zipFile.removeFile(headerNameString);??
  • ????}??
  • ????zipFile.removeFile(dirHeader);??
  • }?
  • 總結

    以上是生活随笔為你收集整理的zip4j -- Java处理zip压缩文件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。