Zip4j

源码地址:https://github.com/srikanth-lingala/zip4j

引入依赖

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.6.4</version>
</dependency>

编译项目,测试路径下会出现测试用文件如下图:

Zip4j

 

创建压缩包等操作代码如下:

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();
    }
}

源码地址:https://github.com/ZhanChaoHan/zip

上一篇:用Python关于 文件的复制移动压缩解压


下一篇:请使用Semaphore编写一个程序,实现以下效果: * 要求: * 1.有10名游客要参观展览室, * 2.展览室同时只允许最多“三个游客”参观, * 3.每个游客参观时间2秒。