源码地址:https://github.com/srikanth-lingala/zip4j
引入依赖
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.6.4</version>
</dependency>
编译项目,测试路径下会出现测试用文件如下图:

创建压缩包等操作代码如下:
package com.jachs.zip.zip4j;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.jachs.zip.ZipApplication;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ExcludeFileFilter;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
/**
* @author zhanchaohan
* 添加压缩
* @see https://github.com/srikanth-lingala/zip4j
*/
@SpringBootTest( classes = ZipApplication.class )
public class Zip4JTest {
String zipPath = Zip4JTest.class.getResource ( "/test-files" ).getPath () + File.separator + "test.zip";
//添加单文件位压缩包
@Test
public void test () throws ZipException {
String filePath = Zip4JTest.class.getResource ( "/test-files/after_deflate_remaining_bytes.bin" ).getPath ();
new ZipFile ( zipPath ).addFile ( filePath );
//or
// new ZipFile(zipPath).addFile(new File(filePath));
}
//添加文件到已存在压缩包
@Test
public void test1 () throws ZipException {
new ZipFile ( zipPath ).addFiles (
Arrays.asList ( new File ( Zip4JTest.class.getResource ( "/test-files/file_PDF_1MB.pdf" ).getPath () ),
new File ( Zip4JTest.class.getResource ( "/test-files/sample_text_large.txt" ).getPath () ) ) );
}
//往已存在压缩包添加文件夹
@Test
public void test2 () throws ZipException {
new ZipFile ( zipPath )
.addFolder ( new File ( Zip4JTest.class.getResource ( "/test-files/sample_directory" ).getPath () ) );
}
//添加指定文件夹到压缩包,过滤掉指定文件
@Test
public void test3 () throws ZipException {
new File ( zipPath ).delete ();
String addFolder = Zip4JTest.class.getResource ( "/test-files" ).getPath ();
ExcludeFileFilter excludeFileFilter = new ExcludeFileFilter () {
@Override
public boolean isExcluded ( File file ) {
System.out.println ( file.getName () );
if ( file.getName ().equals ( "file_PDF_1MB.pdf" ) ) {//匹配文件名过滤掉
return true;
}
if ( file.getName ().equals ( "sample_text_large.txt" ) ) {
return true;
}
return false;
}
};
ZipParameters zipParameters = new ZipParameters ();
zipParameters.setExcludeFileFilter ( excludeFileFilter );
new ZipFile ( zipPath ).addFolder ( new File ( addFolder ), zipParameters );
}
//流的方式添加,
@Test
public void test5 () throws ZipException, FileNotFoundException {
new ZipFile ( "MyStream.zip" ).addStream (
new FileInputStream ( Zip4JTest.class.getResource ( "/test-files/file_PDF_1MB.pdf" ).getPath () ),
new ZipParameters () );
}
//补充test5
@Test
public void test6 () throws ZipException {
ZipParameters zipParameters = new ZipParameters ();
zipParameters.setCompressionMethod ( CompressionMethod.STORE );//压缩方式
new ZipFile ( "filename.zip" )
.addFile ( Zip4JTest.class.getResource ( "/test-files/file_PDF_1MB.pdf" ).getPath (), zipParameters );
}
//创建带密码的压缩包
@Test
public void test7 () throws ZipException {
ZipParameters zipParameters = new ZipParameters ();
zipParameters.setEncryptFiles ( true );
zipParameters.setEncryptionMethod ( EncryptionMethod.AES );
// Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
zipParameters.setAesKeyStrength ( AesKeyStrength.KEY_STRENGTH_256 );
List<File> filesToAdd = Arrays.asList (
new File ( Zip4JTest.class.getResource ( "/test-files/file_PDF_1MB.pdf" ).getPath () ),
new File ( Zip4JTest.class.getResource ( "/test-files/sample_text1.txt" ).getPath () ) );
ZipFile zipFile = new ZipFile ( "passwordfilename.zip", "password".toCharArray () );
zipFile.addFiles ( filesToAdd, zipParameters );
}
//超大压缩包切分为数个小压缩包,指定切分字节大小
@Test
public void test8 () throws ZipException {
new File("efilename.zip").delete ();
List<File> filesToAdd = Arrays.asList (
new File (Zip4JTest.class.getResource ( "/test-archives/cen_dir_entries_diff_order_as_local_entries.zip" ).getPath ()),
new File (Zip4JTest.class.getResource ( "/test-archives/jar-dir-fh-entry-size-2.jar" ).getPath ()) );
ZipFile zipFile = new ZipFile ( "efilename.zip" );
//65536最小的切分字节大小
zipFile.createSplitZipFile ( filesToAdd, new ZipParameters (), true, 65537 ); // using 10MB in this example
}
//同test8,加了密码
@Test
public void test9() throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
List<File> filesToAdd = Arrays.asList(
new File (Zip4JTest.class.getResource ( "/test-archives/cen_dir_entries_diff_order_as_local_entries.zip" ).getPath ()),
new File (Zip4JTest.class.getResource ( "/test-archives/jar-dir-fh-entry-size-2.jar" ).getPath ()) );
ZipFile zipFile = new ZipFile("EQfilename.zip", "password".toCharArray());
zipFile.createSplitZipFile(filesToAdd, zipParameters, true, 65537); // using 10MB in this example
}
}
解压代码如下:
package com.jachs.zip.zip4j; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import com.jachs.zip.ZipApplication; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.FileHeader; /** * @author zhanchaohan 解压缩 * @see https://github.com/srikanth-lingala/zip4j */ @SpringBootTest( classes = ZipApplication.class ) public class unZip4JTest { String zipPath = unZip4JTest.class.getResource ( "/test-files" ).getPath () + File.separator + "test.zip"; //解压 @Test public void test () throws ZipException { new ZipFile ( "filename.zip" ).extractAll ( "/destination_directory" ); } //解压带密码压缩包 @Test public void test1 () throws ZipException { new ZipFile ( "filename.zip", "password".toCharArray () ).extractAll ( "/destination_directory" ); } //解压单文件 @Test public void test2 () throws ZipException { new ZipFile ( "filename.zip" ).extractFile ( "fileNameInZip.txt", "/destination_directory" ); } //解压指定文件夹到指定路径 @Test public void test3 () throws ZipException { new ZipFile ( "filename.zip" ).extractFile ( "folderNameInZip/", "/destination_directory" ); } //同test3指定解压密码 @Test public void test5 () throws ZipException { new ZipFile ( "filename.zip", "password".toCharArray () ).extractFile ( "fileNameInZip.txt", "/destination_directory" ); } /**** * 下面的示例将提取该文件文件名inzip.txt从zip文件到输出目录/目的地目录,并将给文件命名新文件名.txt. * 如果没有新文件名的第三个参数,将使用与zip中的文件相同的名称,在本例中为文件名inzip.txt. * 如果要提取的文件是目录,则newFileName参数将用作目录名。 */ @Test public void test6 () throws ZipException { new ZipFile ( "filename.zip", "password".toCharArray () ).extractFile ( "fileNameInZip.txt", "/destination_directory", "newfileName.txt" ); } //从压缩包中获取数据流 @Test public void test7 () throws IOException { ZipFile zipFile = new ZipFile ( "filename.zip" ); FileHeader fileHeader = zipFile.getFileHeader ( "entry_name_in_zip.txt" ); InputStream inputStream = zipFile.getInputStream ( fileHeader ); } //从压缩包中删除指定文件 @Test public void test8 () throws IOException { new ZipFile ( "filename.zip" ).removeFile ( "fileNameInZipToRemove" ); } //从压缩包中删除指定文件夹 @Test public void test9 () throws IOException { new ZipFile ( "filename.zip" ).removeFile ( "root-folder/folder1/fileNameInZipToRemove" ); } /*** * 如果要确保要删除的文件存在于zip文件中,或者在使用removeFile * API时不想将文件名作为字符串处理,则可以使用另一个重载方法,该方法接收文件头: */ @Test public void test10 () throws IOException { ZipFile zipFile = new ZipFile ( "someZip.zip" ); FileHeader fileHeader = zipFile.getFileHeader ( "fileNameInZipToRemove" ); if ( fileHeader == null ) { // file does not exist } zipFile.removeFile ( fileHeader ); } /*** * 从Zip4j的v2.5.0开始,可以从zip文件中删除多个文件和文件夹。您现在可以传入一个列表,如下代码所示: */ @Test public void test11 () throws IOException { ZipFile zipFile = new ZipFile("someZip.zip"); List<String> filesToRemove = Arrays.asList("file1.txt", "file2.txt", "some-folder/", "some-new-folder-1/somefile.pdf"); zipFile.removeFiles(filesToRemove); } //有三种方法可以使用Zip4j重命名zip文件中的条目。一种方法是传入文件头和新文件名: @Test public void test12 () throws IOException { //第一种方式 ZipFile zipFile = new ZipFile("sample.zip"); FileHeader fileHeader = zipFile.getFileHeader("entry-to-be-changed.pdf"); zipFile.renameFile(fileHeader, "new-file-name.pdf"); //第二种方式 new ZipFile("filename.zip").renameFile("entry-to-be-changed.pdf", "new-file-name.pdf"); //也可以一次更改多个文件名。在这种情况下,您必须使用映射,映射中条目的键是要更改的条目,映射的值是新文件名: Map<String, String> fileNamesMap = new HashMap<>(); fileNamesMap.put("firstFile.txt", "newFileFirst.txt"); fileNamesMap.put("secondFile.pdf", "newSecondFile.pdf"); fileNamesMap.put("some-folder/thirdFile.bin", "some-folder/newThirdFile.bin"); new ZipFile("filename.zip").renameFile("entry-to-be-changed.pdf", "new-file-name.pdf"); //要修改文件夹中的条目名,新文件名还应包含完整的父路径。例如,如果一个条目名为some-条目.pdf在文件夹some folder/some sub folder/中,将此条目名称修改为某个新条目-条目.pdf: new ZipFile("filename.zip").renameFile("some-folder/some-sub-folder/some-entry.pdf", "some-folder/some-sub-folder/new-entry.pdf"); //如果缺少父路径,则该文件将放在zip文件的根目录下。在下面的示例中,重命名文件后,一些新的-条目.pdf将存在于zip文件的根目录下,而不是某个文件夹/某个子文件夹/: new ZipFile("filename.zip").renameFile("some-folder/some-sub-folder/some-entry.pdf", "some-new-entry.pdf"); //这还提供了将条目“移动”到其他文件夹的灵活性。下面的示例将移动-条目.pdf从某个文件夹/某个子文件夹/到要移动到的文件夹/子文件夹/文件也将重命名为新文件-条目.pdf. 要移动文件,请使用相同的文件名而不是新的文件名。 new ZipFile("filename.zip").renameFile("some-folder/some-sub-folder/some-entry.pdf", "folder-to-be-moved-to/sub-folder/new-entry.pdf"); } //这与创建拆分的zip文件相反,也就是说,此功能会将拆分为多个文件的zip文件合并为单个zip文件: @Test public void test13 () throws IOException { new ZipFile("split_zip_file.zip").mergeSplitFiles(new File("merged_zip_file.zip")); } //如果split zip文件(在本例中是split)没有zip文件,此方法将引发异常_文件.zip)不是拆分的zip文件。 @Test public void test14 () throws IOException { List<FileHeader> fileHeaders = new ZipFile("zipfile.zip").getFileHeaders(); fileHeaders.stream().forEach(fileHeader -> System.out.println(fileHeader.getFileName())); } @Test public void test15 () throws IOException { //判断压缩包是否加密 new ZipFile("encrypted_zip_file.zip").isEncrypted(); //判断压缩包是否是切分的压缩包 new ZipFile("split_zip_file.zip").isSplitArchive(); //添加注释 new ZipFile("some_zip_file.zip").setComment("Some comment"); //删除注释 new ZipFile("some_zip_file.zip").setComment(""); //获取注释 new ZipFile("some_zip_file.zip").getComment(); //判断是否有效 new ZipFile("valid_zip_file.zip").isValidZipFile(); } }