{"id":13593272,"url":"https://github.com/srikanth-lingala/zip4j","last_synced_at":"2025-05-13T19:06:04.292Z","repository":{"id":37470658,"uuid":"184887172","full_name":"srikanth-lingala/zip4j","owner":"srikanth-lingala","description":"A Java library for zip files and streams","archived":false,"fork":false,"pushed_at":"2024-06-27T19:05:18.000Z","size":5280,"stargazers_count":2136,"open_issues_count":77,"forks_count":318,"subscribers_count":45,"default_branch":"master","last_synced_at":"2025-04-28T00:28:01.227Z","etag":null,"topics":["java-zip","split-zip","zip-encryption","zip4j"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/srikanth-lingala.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-04T11:39:50.000Z","updated_at":"2025-04-27T17:14:21.000Z","dependencies_parsed_at":"2024-10-29T10:37:39.367Z","dependency_job_id":null,"html_url":"https://github.com/srikanth-lingala/zip4j","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srikanth-lingala%2Fzip4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srikanth-lingala%2Fzip4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srikanth-lingala%2Fzip4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srikanth-lingala%2Fzip4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/srikanth-lingala","download_url":"https://codeload.github.com/srikanth-lingala/zip4j/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010804,"owners_count":21998993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java-zip","split-zip","zip-encryption","zip4j"],"created_at":"2024-08-01T16:01:18.659Z","updated_at":"2025-05-13T19:06:04.236Z","avatar_url":"https://github.com/srikanth-lingala.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"[![javadoc](https://javadoc.io/badge2/net.lingala.zip4j/zip4j/javadoc.svg)](https://javadoc.io/doc/net.lingala.zip4j/zip4j)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.lingala.zip4j/zip4j/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.lingala.zip4j/zip4j)\n\n[![Build Status](https://github.com/srikanth-lingala/zip4j/actions/workflows/maven.yml/badge.svg)](https://github.com/srikanth-lingala/zip4j/actions/workflows/maven.yml)\n[![Android Build Status](https://circleci.com/gh/srikanth-lingala/zip4j-android-test.svg?style=svg)](https://circleci.com/gh/srikanth-lingala/zip4j-android-test)\n[![Known Vulnerabilities](https://snyk.io//test/github/srikanth-lingala/zip4j/badge.svg?targetFile=pom.xml)](https://snyk.io//test/github/srikanth-lingala/zip4j?targetFile=pom.xml)\n\n\n\nZip4j - A Java library for zip files / streams\n=========================\n\n## Thank you\n\nfor rating Zip4j as the best Java library for zip files \u003csup\u003e[[1][1], [2][2], [3][3], [4][4]]\u003c/sup\u003e. It has encouraged me to \nbring this project to life again after a gap of several years. I tried to add some of the important features that \nwere requested over this time, and also made the API much more neater. The newer version (\u003e 2.0.0) now supports streams,\nwhich was understandably, one of the most requested feature. If you have any feedback, bugs to report, feature \nrequests, etc, please open an issue here on GitHub. I will try to address them as soon as I can. I also monitor the\ntag `zip4j` on [Stack Overflow][10].\n\n## About\n\nZip4j is the most comprehensive Java library for zip files or streams. As of this writing, it is the only Java library \nwhich has support for zip encryption, apart from several other features. It tries to make handling zip files/streams \na lot more easier. No more clunky boiler plate code with input streams and output streams. As you can see in the usage \nsection below, working with zip files can now even be a single line of code, compared to [this][5]. I mean no offense\nto the Java's built-in zip support. In fact, this library depends on Java's built-in zip code and it would have been \nsignificantly more ~~complicated~~ challenging if I had to write compression logic as well. But lets be honest, working with zip \nfiles or streams can be a lot of boiler plate code. The main goal of this library is to provide a simple API for all \nusual actions of a zip file or streams by doing the heavy lifting within the library and not have developers worry about\nhaving to deal with streams, etc. Apart from usability, another important goal of this library is to provide support for\nas many zip features as possible, which brings me to:\n\n## Features\n\n* Create, Add, Extract, Update, Remove files from a zip file\n* Support for streams (ZipInputStream and ZipOutputStream)\n* Read/Write password protected zip files and streams\n* Support for both AES and zip standard encryption methods\n* Support for Zip64 format\n* Store (No Compression) and Deflate compression method\n* Create or extract files from split zip files (Ex: z01, z02,...zip)\n* Support for Unicode file names and comments in zip\n* Progress Monitor - for integration into apps and user facing applications\n\n## Background\n\nZip4j was started by me (Srikanth Reddy Lingala) back in 2008/2009, when I realized the lack of support for majority of zip format \nfeatures in Java. And also working with zip files was, as mentioned several times above, a lot of boiler plate code, \nhaving to deal with streams (worse still, it was back in the days when there was no try-with-resources in Java). There\nwas also no comprehensive library which supports zip features. So, I decided to write one, and approximately after a \nyear, the first version was out. The response was truly overwhelming, and I got a lot of support right from the next\nday of release. It was not put on GitHub as git/GitHub was not as popular as it is now. Code was hosted on my website,\nas, guess what, a zip file :). And unfortunately, after a year or two after the initial release, life got busy and I was\nnot able to support Zip4j as much as I wanted to. But the overwhelming encouragement I got over the years made me start working on Zip4j\nonce again, and makes me support Zip4j as much as I can.\n\n## Requirements\n\nJDK 7 or later\u003csup\u003e*\u003c/sup\u003e\n\n\u003csup\u003e*\u003c/sup\u003e Zip4j is written on JDK 8, as some of the features (NIO) that Zip4j supports requires features available only in \nJDK 8. However, considering the fact that Zip4j is widely used in Android, and to support older versions of Android,\nZip4j supports JDK 7 as well. In cases where the feature/class from JDK 8 is missing, Zip4j falls back to the features\n available in JDK 7. In other words, when running on JDK 7, not all features will be supported.\n\n## Maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003enet.lingala.zip4j\u003c/groupId\u003e\n    \u003cartifactId\u003ezip4j\u003c/artifactId\u003e\n    \u003cversion\u003e2.11.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nPlease check the latest version number on [Maven Central][6].\n\n## Usage\n\n### Creating a zip file with single file in it / Adding single file to an existing zip\n\n```java\nnew ZipFile(\"filename.zip\").addFile(\"filename.ext\");\n```\n\n\u0026nbsp;\u0026nbsp; Or\n\n```java\nnew ZipFile(\"filename.zip\").addFile(new File(\"filename.ext\"));\n```\n\n### Creating a zip file with multiple files / Adding multiple files to an existing zip\n\n```java\nnew ZipFile(\"filename.zip\").addFiles(Arrays.asList(new File(\"first_file\"), new File(\"second_file\")));\n```\n\n### Creating a zip file by adding a folder to it / Adding a folder to an existing zip\n\n```java\nnew ZipFile(\"filename.zip\").addFolder(new File(\"/users/some_user/folder_to_add\"));\n```\n\nSince v2.6, it is possible to exclude certain files when adding a folder to zip by using an ExcludeFileFilter\n\n```java\nExcludeFileFilter excludeFileFilter = filesToExclude::contains;\nZipParameters zipParameters = new ZipParameters();\nzipParameters.setExcludeFileFilter(excludeFileFilter);\nnew ZipFile(\"filename.zip\").addFolder(new File(\"/users/some_user/folder_to_add\"), zipParameters);\n```\n\n### Creating a zip file from stream / Adding a stream to an existing zip\n\n```java\nnew ZipFile(\"filename.zip\").addStream(inputStream, new ZipParameters());\n```\n\nPassing in `new ZipParameters()`, as in the above example, will make Zip4j use default zip parameters. Please look at\n[ZipParameters][7] to see the default configuration. \n\n### Creating a zip file of compression method STORE / Adding entries to zip file of compression method STORE\n\nBy default Zip4j uses Deflate compression algorithm to compress files. However, if you would like to not use any\ncompression (called STORE compression), you can do so as shown in the example below: \n\n```java\nZipParameters zipParameters = new ZipParameters();\nzipParameters.setCompressionMethod(CompressionMethod.STORE);\n\nnew ZipFile(\"filename.zip\").addFile(\"fileToAdd\", zipParameters);\n```\n\nYou can similarly pass in zip parameters to all the other examples to create a zip file of STORE compression.\n\n### Creating a password protected zip file / Adding files to an existing zip with password protection\n\n##### AES encryption\n\n```java\nZipParameters zipParameters = new ZipParameters();\nzipParameters.setEncryptFiles(true);\nzipParameters.setEncryptionMethod(EncryptionMethod.AES);\n// 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.\nzipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); \n\nList\u003cFile\u003e filesToAdd = Arrays.asList(\n    new File(\"somefile\"), \n    new File(\"someotherfile\")\n);\n\nZipFile zipFile = new ZipFile(\"filename.zip\", \"password\".toCharArray());\nzipFile.addFiles(filesToAdd, zipParameters);\n```\n\n##### Zip standard encryption\n\nInstead of AES, replace `zipParameters.setEncryptionMethod(EncryptionMethod.AES);` with\n`zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);`. You can omit the line to set AES key strength. As\nthe name suggests, this is only applicable for AES encryption.\n\nIn all the above examples, you can similarly pass in zip parameters with appropriate password configuration to create\na password protected zip file.\n\n### Creating a split zip file\n\nIf you want to split the zip file over several files when the size exceeds a particular limit, you can do so like this:\n\n```java\nList\u003cFile\u003e filesToAdd = Arrays.asList(\n    new File(\"somefile\"), \n    new File(\"someotherfile\")\n);\n\nZipFile zipFile = new ZipFile(\"filename.zip\");\nzipFile.createSplitZipFile(filesToAdd, new ZipParameters(), true, 10485760); // using 10MB in this example\n```\n\nPassing in `new ZipParameters()`, as in the above example, will make Zip4j use default zip parameters. Please look at\n[ZipParameters][7] to see the default configuration. \n\nZip file format specifies a minimum of 65536 bytes (64KB) as a minimum length for split files. Zip4j will throw an\nexception if anything less than this value is specified.\n\nTo create a split zip with password protection, pass in appropriate ZipParameters as shown in the example below:\n\n```java\nZipParameters zipParameters = new ZipParameters();\nzipParameters.setEncryptFiles(true);\nzipParameters.setEncryptionMethod(EncryptionMethod.AES);\n\nList\u003cFile\u003e filesToAdd = Arrays.asList(\n    new File(\"somefile\"), \n    new File(\"someotherfile\")\n);\n\nZipFile zipFile = new ZipFile(\"filename.zip\", \"password\".toCharArray());\nzipFile.createSplitZipFile(filesToAdd, zipParameters, true, 10485760); // using 10MB in this example\n```\n\n### Zip64 format\n\nZip64 is a zip feature which allows support for zip files when the size of the zip file exceeds the maximum that can be \nstored in 4 bytes (i.e., greater than 4,294,967,295 bytes). Traditionally, zip headers have a provision of 4 bytes to store\nfor file sizes. But with growing file sizes compared to a few decades back, zip file format extended support of file \nsizes which extends 4 bytes by adding additional headers which uses 8 bytes for file sizes (compressed and \nuncompressed file sizes). This feature is known as Zip64.\n\nZip4j will automatically make a zip file with Zip64 format and add appropriate headers, when it detects the zip file to be\ncrossing this file size limit. You do not have to explicitly specify any flag for Zip4j to use this feature. \n\n### Extracting all files from a zip\n\n```java\nnew ZipFile(\"filename.zip\").extractAll(\"/destination_directory\");\n```\n\n### Extracting all files from a password protected zip\n\n```java\nnew ZipFile(\"filename.zip\", \"password\".toCharArray()).extractAll(\"/destination_directory\");\n```\n\n### Extracting a single file from zip\n\n```java\nnew ZipFile(\"filename.zip\").extractFile(\"fileNameInZip.txt\", \"/destination_directory\");\n```\n\n### Extracting a folder from zip (since v2.6.0)\n\n```java\nnew ZipFile(\"filename.zip\").extractFile(\"folderNameInZip/\", \"/destination_directory\");\n```\n\n### Extracting a single file from zip which is password protected\n\n```java\nnew ZipFile(\"filename.zip\", \"password\".toCharArray()).extractFile(\"fileNameInZip.txt\", \"/destination_directory\");\n```\n\nSince v2.6.0: If the file name represents a directory, Zip4j will extract all files in the zip that are part of this directory. \n\n### Extracting a single file from zip and giving it a new file name\n\nBelow example will extract the file `fileNameInZip.txt` from the zip file to the output directory `/destination_directory` \nand will give the file the name `newfileName.txt`. Without the third parameter of the new file name, the same name as the\nfile in the zip will be used, which in this case is `fileNameInZip.txt`. If the file being extracted is a directory,\n`newFileName` parameter will be used as the directory name. \n\n```java\nnew ZipFile(\"filename.zip\", \"password\".toCharArray()).extractFile(\"fileNameInZip.txt\", \"/destination_directory\", \"newfileName.txt\");\n```\n\n### Get an input stream for an entry in a zip file\n\n```java\nZipFile zipFile = new ZipFile(\"filename.zip\");\nFileHeader fileHeader = zipFile.getFileHeader(\"entry_name_in_zip.txt\");\nInputStream inputStream = zipFile.getInputStream(fileHeader);\n```\n\nYou can now use this input stream to read content from it/write content to an output stream. Please note that the\nentry/file name is relative to the directory it is in. If `entry_name_in_zip.txt` is in a folder called \"root_folder\" in\nthe zip, then you have to use `zipFile.getFileHeader(\"root_folder/entry_name_in_zip.txt\");`.\n\n### Remove a file/entry from a zip file\n\n```java\nnew ZipFile(\"filename.zip\").removeFile(\"fileNameInZipToRemove\");\n```\n\nIf `fileNameInZipToRemove` represents a folder all the files and folders under this folder will be removed as well\n(this is valid since v2.5.0 of Zip4j. All prior versions remove just the single entry even if it is a folder). \n\nPlease note that the file name is relative the root folder in zip. That is, if the file you want to remove exists in a \nfolder called \"folder1\", which in-turn exists in a folder called \"root-folder\", removing this file from zip has to be done \nas below:\n\n```java\nnew ZipFile(\"filename.zip\").removeFile(\"root-folder/folder1/fileNameInZipToRemove\");\n```\n\nIf you want to be sure that the file you want to remove exists in zip file or if you don't want to deal with file names\nas string when using the `removeFile` API, you can use the other overloaded method which takes in a `FileHeader`:\n\n```java\nZipFile zipFile = new ZipFile(\"someZip.zip\");\nFileHeader fileHeader = zipFile.getFileHeader(\"fileNameInZipToRemove\");\n\nif (fileHeader == null) {\n  // file does not exist\n}\n\nzipFile.removeFile(fileHeader);\n```\n\nSince v2.5.0 of Zip4j, it is possible to remove multiple files and folders from a zip file. You can now pass in a list\nas shown in the code below:\n\n```java\nZipFile zipFile = new ZipFile(\"someZip.zip\");\nList\u003cString\u003e filesToRemove = Arrays.asList(\"file1.txt\", \"file2.txt\", \"some-folder/\", \"some-new-folder-1/somefile.pdf\");\n\nzipFile.removeFiles(filesToRemove);\n```\n\nThe above code will remove `file1.txt`, `file2.txt`, all files and folders under `some-folder` (including `some-folder`)\nand just the entry `somefile.pdf` in folder `some-new-folder-1`. All other files and folders are kept intact in the zip\nfile.\n\n### Rename entries in the zip file\n\nThere are three ways to rename an entry in a zip file with Zip4j. One way is to pass in a file header and the new file \nname:\n\n```java\nZipFile zipFile = new ZipFile(\"sample.zip\");\nFileHeader fileHeader = zipFile.getFileHeader(\"entry-to-be-changed.pdf\");\nzipFile.renameFile(fileHeader, \"new-file-name.pdf\");\n```\n\nSecond way is to pass in just the file name to be changed (instead of the file header), and the new file name. \n\n```java\nnew ZipFile(\"filename.zip\").renameFile(\"entry-to-be-changed.pdf\", \"new-file-name.pdf\");\n```\n\nIt is also possible to change multiple file names at once. In this case you have to use a map, with the key of the entry \nin the map being the entry to be changed, and the value of the map being the new file name:\n\n```java\nMap\u003cString, String\u003e fileNamesMap = new HashMap\u003c\u003e();\nfileNamesMap.put(\"firstFile.txt\", \"newFileFirst.txt\");\nfileNamesMap.put(\"secondFile.pdf\", \"newSecondFile.pdf\");\nfileNamesMap.put(\"some-folder/thirdFile.bin\", \"some-folder/newThirdFile.bin\");\nnew ZipFile(\"filename.zip\").renameFiles(fileNamesMap);\n```\n\nTo modify an entry name which is inside a folder, the new file name should contain the complete parent path as well.\nFor example, if an entry by the name `some-entry.pdf` is in the folder `some-folder/some-sub-folder/`, to modify this \nentry name to `some-new-entry.pdf`:\n\n```java\nnew ZipFile(\"filename.zip\").renameFile(\"some-folder/some-sub-folder/some-entry.pdf\", \"some-folder/some-sub-folder/new-entry.pdf\");\n```\n\nIf the parent path is missing, then the file will be put at the root of the zip file. In the below example, after\nthe file is renamed, `some-new-entry.pdf` will exist at the root of the zip file instead of at `some-folder/some-sub-folder/`:\n\n```java\nnew ZipFile(\"filename.zip\").renameFile(\"some-folder/some-sub-folder/some-entry.pdf\", \"some-new-entry.pdf\");\n```\n\nThis also gives the flexibility to \"move\" the entry to a different folder. The below example will move the \n`some-entry.pdf` from `some-folder/some-sub-folder/` to `folder-to-be-moved-to/sub-folder/` and the file will also be \nrenamed to `new-entry.pdf`. To just move the file, use the same file name instead of a new file name.\n\n```java\nnew ZipFile(\"filename.zip\").renameFile(\"some-folder/some-sub-folder/some-entry.pdf\", \"folder-to-be-moved-to/sub-folder/new-entry.pdf\");\n```\n\nIf the entry being modified is a directory, all entries that are part of that directory will be renamed so that all of \nthem have the new folder name as parent. In zip format, all entry names under a directory will contain the full name as their file name.\nFor example if there is an entry by the name `filename.txt` inside a directory `directoryName`, the file name for the entry \nwill be `directoryName/filename.txt`. And if the name of the directory has now been changed to `newDirectoryName`, the\nentry under it will also be changed to `newDirectoryName/filename.txt`, so when the zip file is extracted, \n`filename.txt` will be under `newDirectoryName`.\n\nZip file format does not allow modifying split zip files, and Zip4j will throw an exception if an attempt is made to \nrename files in a split zip file.\n\n### Merging split zip files into a single zip\n\nThis is the reverse of creating a split zip file, that is, this feature will merge a zip file which is split across \nseveral files into a single zip file:\n\n```java\nnew ZipFile(\"split_zip_file.zip\").mergeSplitFiles(new File(\"merged_zip_file.zip\"));\n```\n\nThis method will throw an exception if the split zip file (in this case `split_zip_file.zip`) is not a split zip file.\n\n### List all files in a zip\n\n```java\nList\u003cFileHeader\u003e fileHeaders = new ZipFile(\"zipfile.zip\").getFileHeaders();\nfileHeaders.stream().forEach(fileHeader -\u003e System.out.println(fileHeader.getFileName()));\n```\n\nYou can get all other information from the `FileHeader` object corresponding to each file/entry in the zip.\n\n### Check if a zip file is password protected\n\n```java\nnew ZipFile(\"encrypted_zip_file.zip\").isEncrypted();\n```\n\n### Check if a zip file is a split zip file\n\n```java\nnew ZipFile(\"split_zip_file.zip\").isSplitArchive();\n```\n\n### Set comment for a zip file\n\n```java\nnew ZipFile(\"some_zip_file.zip\").setComment(\"Some comment\");\n```\n\n### Remove comment of a zip file\n\n```java\nnew ZipFile(\"some_zip_file.zip\").setComment(\"\");\n```\n\n### Get comment of a zip file\n\n```java\nnew ZipFile(\"some_zip_file.zip\").getComment();\n```\n\n### Check if a zip file is valid\n\nNote: This will only check for the validity of the headers and not the validity of each entry in the zip file.\n\n```java\nnew ZipFile(\"valid_zip_file.zip\").isValidZipFile();\n```\n\n## Working with streams\n\n### Adding entries with ZipOutputStream\n\n```java\nimport net.lingala.zip4j.io.outputstream.ZipOutputStream;\nimport net.lingala.zip4j.model.ZipParameters;\nimport net.lingala.zip4j.model.enums.AesKeyStrength;\nimport net.lingala.zip4j.model.enums.CompressionMethod;\nimport net.lingala.zip4j.model.enums.EncryptionMethod;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.List;\n\npublic class ZipOutputStreamExample {\n\n  public void zipOutputStreamExample(File outputZipFile, List\u003cFile\u003e filesToAdd, char[] password,  \n                                     CompressionMethod compressionMethod, boolean encrypt,\n                                     EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength)\n      throws IOException {\n\n    ZipParameters zipParameters = buildZipParameters(compressionMethod, encrypt, encryptionMethod, aesKeyStrength);\n    byte[] buff = new byte[4096];\n    int readLen;\n\n    try(ZipOutputStream zos = initializeZipOutputStream(outputZipFile, encrypt, password)) {\n      for (File fileToAdd : filesToAdd) {\n\n        // Entry size has to be set if you want to add entries of STORE compression method (no compression)\n        // This is not required for deflate compression\n        if (zipParameters.getCompressionMethod() == CompressionMethod.STORE) {\n          zipParameters.setEntrySize(fileToAdd.length());\n        }\n\n        zipParameters.setFileNameInZip(fileToAdd.getName());\n        zos.putNextEntry(zipParameters);\n\n        try(InputStream inputStream = new FileInputStream(fileToAdd)) {\n          while ((readLen = inputStream.read(buff)) != -1) {\n            zos.write(buff, 0, readLen);\n          }\n        }\n        zos.closeEntry();\n      }\n    }\n  }\n\n  private ZipOutputStream initializeZipOutputStream(File outputZipFile, boolean encrypt, char[] password) \n      throws IOException {\n    \n    FileOutputStream fos = new FileOutputStream(outputZipFile);\n\n    if (encrypt) {\n      return new ZipOutputStream(fos, password);\n    }\n\n    return new ZipOutputStream(fos);\n  }\n\n  private ZipParameters buildZipParameters(CompressionMethod compressionMethod, boolean encrypt,\n                                           EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength) {\n    ZipParameters zipParameters = new ZipParameters();\n    zipParameters.setCompressionMethod(compressionMethod);\n    zipParameters.setEncryptionMethod(encryptionMethod);\n    zipParameters.setAesKeyStrength(aesKeyStrength);\n    zipParameters.setEncryptFiles(encrypt);\n    return zipParameters;\n  }\n}\n```\n\n### Extract files with ZipInputStream\n\n```java\nimport net.lingala.zip4j.io.inputstream.ZipInputStream;\nimport net.lingala.zip4j.model.LocalFileHeader;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\npublic class ZipInputStreamExample {\n  \n  public void extractWithZipInputStream(File zipFile, char[] password) throws IOException {\n    LocalFileHeader localFileHeader;\n    int readLen;\n    byte[] readBuffer = new byte[4096];\n\n    InputStream inputStream = new FileInputStream(zipFile);\n    try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, password)) {\n      while ((localFileHeader = zipInputStream.getNextEntry()) != null) {\n        File extractedFile = new File(localFileHeader.getFileName());\n        try (OutputStream outputStream = new FileOutputStream(extractedFile)) {\n          while ((readLen = zipInputStream.read(readBuffer)) != -1) {\n            outputStream.write(readBuffer, 0, readLen);\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## Working with Progress Monitor\n\nProgressMonitor makes it easier for applications (especially user facing) to integrate Zip4j. It is useful to show\nprogress (example: updating a progress bar, displaying the current action, show file name being worked on, etc.). To use\nProgressMonitor, you have to set `ZipFile.setRunInThread(true)`. This will make any actions being done on the zip file\nto run in a background thread. You can then access ProgressMonitor `Zipfile.getProgressMonitor()` and get details of the\ncurrent action being done along with the percentage work done, etc. Below is an example:\n\n```java\nZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);\nProgressMonitor progressMonitor = zipFile.getProgressMonitor();\n\nzipFile.setRunInThread(true);\nzipFile.addFolder(new File(\"/some/folder\"));\n\nwhile (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {\n  System.out.println(\"Percentage done: \" + progressMonitor.getPercentDone());\n  System.out.println(\"Current file: \" + progressMonitor.getFileName());\n  System.out.println(\"Current task: \" + progressMonitor.getCurrentTask());\n\n  Thread.sleep(100);\n}\n\nif (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {\n  System.out.println(\"Successfully added folder to zip\");\n} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {\n  System.out.println(\"Error occurred. Error message: \" + progressMonitor.getException().getMessage());\n} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {\n  System.out.println(\"Task cancelled\");\n}\n```\n\nNote that in the above example, `addFolder()` will almost immediately return back the control to the caller. The client\ncode can then perform a loop until the state gets back to \"Ready\" as shown in the above example.\n\nSimilarly, ProgressMonitor can be used with other actions like, `addFiles`, `removeFiles` and `extractFiles`.\n\n## Contribution\n\nIt is hard to find as much free time as I used to have when I first started Zip4j back in 2009. I would\nhighly appreciate any support I can get for this project. You can fork this project, and send me pull requests for\nany bug fixes, issues mentioned here or new features. If you need any support in understanding the code or zip specification, \njust drop me a mail and I will help you as best as I can. (See FAQ for my email address.)\n\n## FAQ\n\n1. **Why do I have to pass in password as char array and not as a string?**\n\n    [That's why][8] \n\n2. **How can I contact you?**\n\n    srikanth.mailbox@gmail.com\n\n3. **Are unicode file names supported?**\n\n    Yes, unicode file names (UTF-8) are supported as specified by the zip format specification. Zip4j will use UTF-8 file\nname and file comment encoding when creating a zip file. When extracting a zip file, Zip4j will only use UTF-8 encoding,\nonly if the appropriate header flag is set as specified by zip file format specification. If this flag is not set, \nZip4j will use CP437 encoding which only supports extended ASCII characters.\n \n4. **Where can I find zip file format specification?**\n\n    [Here][9]\n\n5. **Why are there so many changes in version 2.x compared to 1.x?**\n\n    Because when version 1.x was written back in 2009, Zip4j was badly in need of a face-lift and code modernization. Also, my \ncoding standards have improved over the years (or at least that's what I like to think). Although I am proud of \nthe work I did with Zip4j back in 2009, some parts of the code make me feel like hiding my face in shame. One such example\nis the usage of `ArrayList` instead of `List`. API and code should look much neater now. And also, Zip4j now supports\na minimum of JRE 8, as compared to JRE 5 with 1.x, which obviously will bring some nice features that I can make use of. (For\nexample: no more explicitly closing the streams all over the code). If you still feel like something can be improved (and\nI am pretty sure that there are things to be improved), please let me know by opening an issue here or writing to me \n(my email address is in point #2 above).\n\n6. **What are the licensing conditions for older releases of Zip4j?**\n\n    All releases of Zip4j, from version 1.0, are licensed under Apache License 2.0\n\n\n[1]: https://stackoverflow.com/questions/9324933/what-is-a-good-java-library-to-zip-unzip-files\n[2]: https://stackoverflow.com/questions/5362364/java-library-to-work-with-zip-files\n[3]: https://stackoverflow.com/questions/166340/recommendations-on-a-free-library-to-be-used-for-zipping-files\n[4]: https://stackoverflow.com/questions/18201279/file-compression-library-for-java/18201553\n[5]: https://www.baeldung.com/java-compress-and-uncompress\n[6]: https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j\n[7]: https://javadoc.io/doc/net.lingala.zip4j/zip4j/latest/net/lingala/zip4j/model/ZipParameters.html#ZipParameters--\n[8]: https://www.baeldung.com/java-storing-passwords\n[9]: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT\n[10]: https://stackoverflow.com/questions/tagged/zip4j\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrikanth-lingala%2Fzip4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsrikanth-lingala%2Fzip4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrikanth-lingala%2Fzip4j/lists"}