Preface
More than a month ago, the project needed to understand how to process ZIP files in the Java language, and tried a variety of open-source projects and wrote several blogs to record them:
- Http://blog.csdn.net/zhangyihui1986/article/details/7724229
- Http://blog.csdn.net/zhangyihui1986/article/details/7723649
- Http://blog.csdn.net/zhangyihui1986/article/details/7724616
Zip4j, as the ultimate solution to solve my problem, was originally found on the search engine at the beginning, but due to tianchao's network environment problems, zip4j's official website has never been accessible. In the end, I took many other steps. During this period, I tried the JDK zip package and Apache zip solution, I also tried other open-source frameworks such as winzipaes, which did not meet my own needs. Finally, I had to download zip4j from the agent and try it out. It was incredibly powerful, everywhere is invincible...
If necessary, you can download this open-source project from the official zip4j Website:
Http://www.lingala.net/zip4j/
However, please note that you may not be able to access the service directly. If you cannot access the service normally, please prepare your own proxy access. If you are too troublesome, please download it here:
Http://download.csdn.net/detail/zhangyihui1986/4418509
This is my csdn resource link. It takes 3 points for downloading. If you do not score much, you can leave a message to ask for it. Haha... I also need points. Please forgive me!
The resources downloaded on the official website do not seem to contain the API help documentation. I used the source code to generate a copy and paste it into my resource file, hoping to help you.
Official description of zip4j
(I translated it by myself. The English is not good, haha ...)
Key features (main features ):
- Create, add, extract, update, remove files from a zip file
Create, add, extract, update, and remove ZIP files
- Read/write password protected ZIP files
(Read and write password-protected ZIP files)
- Supports AES 128/256 Encryption
(Supports AES 128/256 encryption)
- Supports standard ZIP Encryption
(Supports standard ZIP encryption)
- Supports zip64 format
(Zip64 format supported)
- Supports store (no compression) and deflate Compression Method
(Store (non-compressed) and deflate compression methods are supported-not quite clear)
- Create or extract files from split ZIP files (ex: z01, z02,....zip)
(Create and Extract files for multipart ZIP files)
- Supports Unicode file names
(Supports Unicode encoding file names)
- Progress Monitor
(Progress Monitoring)
From the main features above, we can see that zip4j is very powerful and can be used to write a zip file management software similar to the pressure, however, we may use it for some simple decompression and compression operations. Other features are Rarely touched, and I am the same...
Usage notes
Zip4j uses UTF-8 encoding by default, so it supports Chinese, also supports password, and supports a variety of compression algorithms, can be said to be powerful, but it is very simple to use, of course, if the demand is more complex, so you have to study it. If you simply extract a zip file, you only need to perform the following steps:
Public static void unzip (File zipfile, string DEST, string passwd) throws zipexception {zipfile zfile = new zipfile (zipfile); // create zipfilefirst to indicate to the. ZIP file zfile on the current file. setfilenamecharset ("GBK"); // sets the file name encoding. In the GBK system, set if (! Zfile. isvalidzipfile () {// verify whether the. ZIP file is valid, including whether the file exists, whether it is a zip file, and whether it is damaged. Throw new zipexception ("the compressed file is invalid and may be damaged. ");} file destdir = new file (DEST); // extract the directory if (destdir. isdirectory ()&&! Destdir. exists () {destdir. mkdir ();} If (zfile. isencrypted () {zfile. setpassword (passwd. tochararray (); // set the password} zfile. extractall (DEST); // extract the file to the decompressed directory (decompress )}
Of course, it is very easy to compress a specified file into a zip file. No code is posted here. For more information, see the complete example below.
Tip: if the file name in the compressed file to be decompressed contains Chinese characters, you must note that the character set of the file name is set.
zFile.setFileNameCharset("GBK");
This method must be called first. How many times should it be called first? In fact, it is best to set the zipfile after it is created, at least in
zFile.isValidZipFile()
This method was called before calling. I had to wait for a long time for this problem during the application. I finally checked the source code to understand it. It seems that zipfile sets the encoding in the verification method, the file name encoding will not be changed in the future.
Complete example
The following is an example of self-writing, where the monks are not easy to learn, are not talented, and the quality of the Code to be written is poor. I hope it will play a role in attracting others.
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.zip 4j. core. zipfile; import net.lingala.zip 4j. exception. zipexception; import net.lingala.zip 4j. model. fileheader; import net.lingala.zip 4j. model. zipparameters; import net.lingala.zip 4j. util. zip4jconstants;/*** zip compressed file Tool class * supports password * dependent zip4j open source project (http://www.lingala.net/zip4j) * Version 1.3.1 * @ author ninemax */public class compressutil {/*** unzip the specified ZIP file to the specified directory using the given password * <p> * If the specified directory does not exist, can be created automatically, invalid path will cause an exception to be thrown * @ Param zip specified zip compressed file * @ Param DEST decompress directory * @ Param passwd ZIP file Password * @ return decompressed file array * @ throws zipexception: the compressed file is damaged or cannot be decompressed. */public static file [] unzip (string zip, string DEST, string passwd) throws zip1_tio N {file zipfile = new file (ZIP); Return unzip (zipfile, DEST, passwd );} /*** extract the specified ZIP file with the given password to the current directory * @ Param zip the specified ZIP file * @ Param passwd ZIP file Password * @ return unzip the file Array * @ throws zipexception: the compressed file is damaged or fails to be decompressed. */public static file [] unzip (string zip, string passwd) throws zipexception {file zipfile = new file (ZIP); file parentdir = zipfile. getparentfile (); Return unzip (zipfile, parentdir. getabsolutepat H (), passwd);}/*** decompress the specified ZIP file with the given password to the specified directory * <p> * If the specified directory does not exist, it can be created automatically, invalid path will cause an exception to be thrown * @ Param zip specified zip compressed file * @ Param DEST decompress directory * @ Param passwd ZIP file Password * @ return decompressed file array * @ throws zipexception: the compressed file is damaged or fails to be decompressed. */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 ("the compressed file is invalid and may be damaged. ");} 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: headerlist) {If (! Fileheader. isdirectory () {extractedfilelist. add (new file (destdir, fileheader. getfilename ();} file [] extractedfiles = new file [extractedfilelist. size ()]; extractedfilelist. toarray (extractedfiles); Return extractedfiles;}/*** compress the specified file to the current folder * @ Param SRC the specified file to be compressed * @ return the absolute path of the compressed file, if it is null, compression fails. */public static string zip (string SRC) {return zip (SRC, null);}/*** use the given password to compress the specified file or folder to the current directory * @ Param SRC file to be compressed * @ Param passwd password used for compression * @ return the absolute path of the final compressed file. If it is null, compression fails. */public static string zip (string SRC, string passwd) {return zip (SRC, null, passwd );} /*** use the given password to compress the specified file or folder to the current directory * @ Param SRC file to be compressed * @ Param DEST compression file storage path * @ Param passwd compression password * @ return the absolute path of the compressed file, if it is null, compression fails. */public static string zip (string SRC, string DEST, string passwd) {return zip (SRC, DEST, true, passwd );}/*** Use the given password to compress the specified file or folder to the specified location. * <p> * DEST can be used to upload the absolute path of the final compressed file, the directory, or null or "". <br/> * If null or "" is passed, the compressed file is stored in the current directory, that is, the same directory as the source file. The compressed file name is used as the source file name, And the suffix is. Zip. <br/> * suffix is used as the suffix. * @ Param SRC: Path of the file or folder to be compressed * @ Param DEST: Path of the compressed file * @ Param iscreatedir: whether to create a directory in the compressed file, which is only valid when the compressed file is a directory. <br/> * if it is false, files in the directory are directly compressed to the compressed file. * @ Param passwd the password used for compression * @ return the absolute path of the final compressed file, if it is n Otherwise, the compression fails. */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); // The compression method parameters. setcompressionlevel (zip4jconstants. deflate_level_normal); // compression level if (! Stringutils. isempty (passwd) {parameters. setencryptfiles (true); parameters. setencryptionmethod (zip4jconstants. enc_method_standard); // The encryption method parameters. setpassword (passwd. tochararray ();} Try {zipfile = new zipfile (DEST); If (srcfile. isdirectory () {// if you do not create a directory, the files under the given directory will be directly compressed to the compressed file, that is, there is no directory structure 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;}/*** creates a path for storing compressed files. If no path exists, * file names or directories may be input or not transmitted, this method is used to convert the final compressed file Storage path * @ Param srcfile source file * @ Param destparam compression target path * @ return correct compression file storage path */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 (". "); destpa Ram = srcfile. getparent () + file. separator + filename + ". zip ";}} else {createdestdirectoryifnecessary (destparam); // if the specified path does not exist, create it 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;}/*** required Create a directory for storing compressed files. For example, the specified storage path is not created * @ Param destparam, it is possible that this path is not created */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 ();//}}}
There are too many things to learn, and there is not much time (maybe just an excuse) to study it. The above example is just a simple decompression and compression operation; however, in use, we can find that the zip4j function is relatively complete. If you need more support, you should study it carefully. Maybe it will not disappoint you...
Supplement
Delete the directory in the compressed file
A friend asked me how to delete the directory in the compressed file. I would like to add it here.
Using zip4j to delete directories in compressed files, you can easily think of this method after checking the API:
Zipfile = new zipfile ("D: \ FeiQ-V2.5.zip"); zipfile. setfilenamecharset ("GBK"); zipfile. removefile ("sounds/"); // sounds is a directory in the ZIP file.
However, this method of directly deleting non-empty directories in a compressed file will not succeed, and you will see that the ZIP file has not changed at all, although the fileheader corresponding to the directory has been deleted (this means that if all the files under the directory are deleted at this time, the directory will disappear ); therefore, we need to delete all the files in the directory and then delete the directory. Based on this idea, we can easily form the following code:
Void removedirfromziparchive (string file, string removedir) throws zipexception {// create a zipfile and set zipfile = new zipfile (File); zipfile. setfilenamecharset ("GBK"); // Add the path separator if (! Removedir. endswith (file. separator) removedir + = file. separator; // If the directory does not exist, the system returns fileheader dirheader = zipfile. getfileheader (removedir); If (null = dirheader) return; // traverses all the fileheaders In the compressed file and deletes list allheaders = zipfile from the sub-files in the specified Delete directory. 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) ;}// finally Delete the specified directory zipfile. removefile (dirheader );}
This still cannot solve the problem. If you do this, you will get a java. Lang. indexoutofboundsexception exception. Why does the seemingly normal code report an index out-of-bounds exception? In fact, the list we get through the zipfile. getfileheaders () method will change with the delete operation in the traversal. That is to say, if we delete a fileheader, it will be reflected in the List. Each time a fileheader is successfully deleted, the length of the list is reduced by 1, And I increases progressively between the initial length of 0 and list. After repeated times, an out-of-bounds exception may occur.
To avoid this, we can do more operations. For example, we can do not delete objects during traversal, but only record the objects to be deleted and delete them after traversal, finally, delete the directory. After testing, this solution can solve the problem.
Simple sample code:
Void removedirfromziparchive (string file, string removedir) throws zipexception {// create a zipfile and set zipfile = new zipfile (File); zipfile. setfilenamecharset ("GBK"); // Add the path separator if (! Removedir. endswith (file. separator) removedir + = file. separator; // If the directory does not exist, the system returns fileheader dirheader = zipfile. getfileheader (removedir); If (null = dirheader) return; // traverses all the fileheaders In the compressed file and saves the sub-file names in the specified Delete directory to list headerslist = zipfile. getfileheaders (); List <string> removeheadernames = new arraylist <string> (); For (INT I = 0, Len = headerslist. size (); I <Len; I ++) {fileheader Subheader = (fileheader) Head Erslist. Get (I); If (Subheader. getfilename (). startswith (dirheader. getfilename ())&&! Subheader. getfilename (). equals (dirheader. getfilename () {removeheadernames. add (Subheader. getfilename () ;}}// traverses and deletes all the sub-files under the specified directory, and finally deletes the specified directory (this is an empty directory) for (string headernamestring: removeheadernames) {zipfile. removefile (headernamestring);} zipfile. removefile (dirheader );}
There may be other ways to solve this problem. If you need it, leave it for you to solve it.