Zip4j

repository·master·Indexed 24 days ago

https://github.com/srikanth-lingala/zip4j

A comprehensive Java library for handling zip files and streams, providing a simplified API for creation, extraction, and encryption. Key features include support for AES and standard zip encryption, Zip64 format, split zip files, and Unicode file names. It supports JDK 7 or later and includes a ProgressMonitor for tracking long-running operations.

Tokens
5.5K
Snippets
12
Records
18
Agent score
31%

What's inside Zip4j

  1. Overview of Zip4j features

    master

    Zip4j is a comprehensive Java library designed to simplify working with zip files and streams. It aims to reduce boilerplate code compared to Java's built-in zip support by handling the heavy lifting of stream management and complex zip operations.

    Key features include:

    • File Operations: Create, Add, Extract, Update, and Remove files from a zip file.
    • Stream Support: Support for ZipInputStream and ZipOutputStream.
    • Encryption: Read/Write password-protected zip files and streams using both AES and standard zip encryption methods.
    • Format Support: Support for Zip64 format and split zip files (e.g., .z01, .z02, ..., .zip).
    • Compression: Support for both Store (no compression) and Deflate compression methods.
    • Unicode: Support for Unicode file names and comments.
    • Progress Monitoring: Includes a Progress Monitor for integration into user-facing applications.
  2. Zip4j requirements

    master

    Zip4j requires JDK 7 or later.

    Note: While the library is written using JDK 8 features (such as NIO), it includes fallback mechanisms to support JDK 7 for compatibility with older Android environments. However, when running on JDK 7, some features may not be available.

  3. Unicode support in Zip4j

    master

    Zip4j supports Unicode file names (UTF-8) as per the zip format specification.

    • Creation: Zip4j uses UTF-8 encoding for file names and file comments when creating zip files.
    • Extraction: Zip4j uses UTF-8 encoding during extraction only if the appropriate header flag is set in the zip file. If this flag is missing, Zip4j falls back to CP437 encoding (extended ASCII).
  4. Security: Why passwords use char[] instead of String

    master
    Zip4j requires passwords to be passed as char[] rather than String. This is a security best practice to allow the developer to overwrite the array in memory after use, preventing sensitive data from lingering in the heap as immutable String objects.
  5. Configure compression methods and encryption

    master

    Zip4j uses the Deflate algorithm by default. You can change this using ZipParameters.

    Using STORE (no compression):

    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setCompressionMethod(CompressionMethod.STORE);
    new ZipFile("filename.zip").addFile("fileToAdd", zipParameters);

    AES Encryption: To protect files with AES encryption, set the encryption method and key strength. AES 256 is the default.

    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setEncryptFiles(true);
    zipParameters.setEncryptionMethod(EncryptionMethod.AES);
    zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); 
    
    List<File> filesToAdd = Arrays.asList(new File("somefile"), new File("someotherfile"));
    ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
    zipFile.addFiles(filesToAdd, zipParameters);

    Zip Standard Encryption: Replace the AES method with EncryptionMethod.ZIP_STANDARD.

    zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setEncryptFiles(true);
    zipParameters.setEncryptionMethod(EncryptionMethod.AES);
    zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); 
    
    List<File> filesToAdd = Arrays.asList(
        new File("somefile"), 
        new File("someotherfile")
    );
    
    ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
    zipFile.addFiles(filesToAdd, zipParameters);
  6. Install Zip4j via Maven

    master

    To use Zip4j in your Java project, add the following dependency to your pom.xml file. Ensure you check Maven Central for the latest version number.

    <dependency>
        <groupId>net.lingala.zip4j</groupId>
        <artifactId>zip4j</artifactId>
        <version>2.11.6</version>
    </dependency>
  7. Monitor progress with ProgressMonitor

    master

    To integrate progress tracking (e.g., for progress bars) in user-facing applications, use the ProgressMonitor.

    1. Call ZipFile.setRunInThread(true) to ensure zip operations run in a background thread.
    2. Retrieve the monitor via ZipFile.getProgressMonitor().
    3. The operation (like addFolder, addFiles, removeFiles, or extractFiles) will return control to the caller immediately.
    4. Poll the monitor in a loop until progressMonitor.getState() returns ProgressMonitor.State.READY.

    Available information from the monitor:

    • getPercentDone(): Percentage of work completed.
    • getFileName(): The current file being processed.
    • getCurrentTask(): The current action being performed.
    • getResult(): Returns SUCCESS, ERROR, or CANCELLED once finished.
    • getException(): Returns the exception if the result is ERROR.
    ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
    ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
    
    zipFile.setRunInThread(true);
    zipFile.addFolder(new File("/some/folder"));
    
    while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {
      System.out.println("Percentage done: " + progressMonitor.getPercentDone());
      System.out.println("Current file: " + progressMonitor.getFileName());
      System.out.println("Current task: " + progressMonitor.getCurrentTask());
    
      Thread.sleep(100);
    }
    
    if (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {
      System.out.println("Successfully added folder to zip");
    } else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {
      System.out.println("Error occurred. Error message: " + progressMonitor.getException().getMessage());
    } else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {
      System.out.println("Task cancelled");
    }
  8. Extract files and folders from a zip

    master

    Zip4j provides several ways to extract content from an archive.

    Extract all files:

    new ZipFile("filename.zip").extractAll("/destination_directory");

    Extract a single file:

    new ZipFile("filename.zip").extractFile("fileNameInZip.txt", "/destination_directory");

    Extract a folder (since v2.6.0): If the filename represents a directory, all files within that directory will be extracted.

    new ZipFile("filename.zip").extractFile("folderNameInZip/", "/destination_directory");

    Extract with a new filename: You can rename the file during extraction by providing a third parameter.

    new ZipFile("filename.zip").extractFile("fileNameInZip.txt", "/destination_directory", "newfileName.txt");

    Extracting password protected files: Pass the password as a char[] to the ZipFile constructor.

    new ZipFile("filename.zip", "password".toCharArray()).extractAll("/destination_directory");
    new ZipFile("filename.zip").extractAll("/destination_directory");
  9. Create and merge split zip files

    master

    Split zip files allow you to break a large archive into multiple smaller files based on a size limit.

    Creating a split zip: Pass the list of files, ZipParameters, a boolean for whether to use encryption, and the split size in bytes. The minimum split size is 65,536 bytes (64KB).

    List<File> filesToAdd = Arrays.asList(new File("somefile"), new File("someotherfile"));
    ZipFile zipFile = new ZipFile("filename.zip");
    zipFile.createSplitZipFile(filesToAdd, new ZipParameters(), true, 10485760); // 10MB split

    Merging split files: To combine a split archive back into a single zip file:

    new ZipFile("split_zip_file.zip").mergeSplitFiles(new File("merged_zip_file.zip"));

    Note: mergeSplitFiles will throw an exception if the source is not a split archive.

    ZipFile zipFile = new ZipFile("filename.zip");
    zipFile.createSplitZipFile(filesToAdd, new ZipParameters(), true, 10485760);
  10. Exclude files when adding a folder to a zip

    master

    Since v2.6, you can use an ExcludeFileFilter to prevent specific files from being included when adding a folder. The filter is a functional interface that returns true for files that should be excluded.

    ExcludeFileFilter excludeFileFilter = filesToExclude::contains;
    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setExcludeFileFilter(excludeFileFilter);
    new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"), zipParameters);
    ExcludeFileFilter excludeFileFilter = filesToExclude::contains;
    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setExcludeFileFilter(excludeFileFilter);
    new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"), zipParameters);
  11. Add files and folders to a zip file

    master

    You can create new zip files or add content to existing ones using ZipFile. Zip4j supports adding single files, multiple files, entire folders, and input streams.

    Adding a single file:

    new ZipFile("filename.zip").addFile("filename.ext");

    Adding multiple files:

    new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));

    Adding a folder:

    new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"));

    Adding a stream:

    new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());

    Note: Passing new ZipParameters() uses default configuration.

    new ZipFile("filename.zip").addFile("filename.ext");
  12. Rename or move entries in a zip file

    master

    Zip4j allows renaming individual files, multiple files, or entire directories.

    Rename a single file:

    new ZipFile("filename.zip").renameFile("old-name.pdf", "new-name.pdf");

    Rename multiple files: Use a Map<String, String> where the key is the current name and the value is the new name.

    Map<String, String> fileNamesMap = new HashMap<>();
    fileNamesMap.put("firstFile.txt", "newFileFirst.txt");
    new ZipFile("filename.zip").renameFiles(fileNamesMap);

    Moving an entry: To move an entry to a different folder, include the new path in the new name. If you omit the parent path in the new name, the file will be moved to the root of the zip.

    // Moves and renames
    new ZipFile("filename.zip").renameFile("some-folder/old.pdf", "new-folder/new.pdf");
    
    // Moves to root
    new ZipFile("filename.zip").renameFile("some-folder/old.pdf", "new.pdf");

    Note: Renaming is not supported for split zip files.

    new ZipFile("filename.zip").renameFile("entry-to-be-changed.pdf", "new-file-name.pdf");