{"id":17881308,"url":"https://github.com/col-e/ll-java-zip","last_synced_at":"2026-03-16T09:33:12.057Z","repository":{"id":39916095,"uuid":"461857682","full_name":"Col-E/LL-Java-Zip","owner":"Col-E","description":"Lower level ZIP support for Java","archived":false,"fork":false,"pushed_at":"2024-08-14T05:25:29.000Z","size":3329,"stargazers_count":34,"open_issues_count":2,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-15T05:57:39.014Z","etag":null,"topics":["java","zip","zipfile"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Col-E.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":"2022-02-21T12:45:37.000Z","updated_at":"2024-08-15T05:57:39.015Z","dependencies_parsed_at":"2024-08-14T06:04:11.470Z","dependency_job_id":null,"html_url":"https://github.com/Col-E/LL-Java-Zip","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Col-E%2FLL-Java-Zip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Col-E%2FLL-Java-Zip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Col-E%2FLL-Java-Zip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Col-E%2FLL-Java-Zip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Col-E","download_url":"https://codeload.github.com/Col-E/LL-Java-Zip/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221826620,"owners_count":16887196,"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","zipfile"],"created_at":"2024-10-28T12:36:33.789Z","updated_at":"2026-03-16T09:33:12.052Z","avatar_url":"https://github.com/Col-E.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LLJ-ZIP [![](https://jitpack.io/v/Col-E/LL-Java-Zip.svg)](https://jitpack.io/#Col-E/LL-Java-Zip) ![](https://github.com/Col-E/LL-Java-Zip/actions/workflows/display_test_results.yml/badge.svg)\n\n\nA closer to the spec implementation of ZIP parsing for Java.\n\n## Relevant ZIP information\n \n**[Official spec](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)**\n\nThe notes and structure outlines are the basis for most of LLJ-ZIP.\n\n**[JVM zip parsing](https://github.com/openjdk/jdk/tree/6701eba736ac51db4b0d0d7db6c7bdd4ae8a1c16/src/java.base/share/native/libzip) \u0026 [JLI](https://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.base/share/native/libjli/parse_manifest.c#L120)**\n\nThe JVM zip reader implementation is based off this piece.\n\n\u003e This is a zip format reader for seekable files, **that tolerates leading and trailing garbage**, \n\u003e and **tolerates having had internal offsets adjusted for leading garbage** _(as with Info-Zip's zip -A)_.\n\nBut that's not all it does. That's just what that one comment says. Some other fun quirks of the JVM zip parser:\n\n- The end central directory entry is found by scanning from the end of the file, rather than from the beginning.\n- The central directory values are authoritative. Names/values defined by the local file headers are ignored.\n- The file data of local file headers is not size bound by the file header's compressed size field. Instead, it uses the central directory header's declared size.\n- Class names are allowed to end in trailing `/` which most tools interpret as directories.\n\n## Additional features\n\n- Reads ZIP files using `MemorySegment` backed mapped files.\n- Highly configurable, offering 3 ZIP reading strategies out of the box _(See `ZipIO` for convenience calls)_\n    - Std / Forward scanning: Scans for `EndOfCentralDirectory` from the front of the file, like many other tools\n    - Naive: Scans only for `LocalFileHeader` values from the front of the file, the fastest implementation, but obviously naive\n    - JVM: Matches the behavior of the JVM's ZIP parser, including a number of odd edge cases. Useful for opening JAR files to mirror `java -jar \u003cpath\u003e` behavior.\n- Inputs do not have to be on-disk to be read, you can supply zip data in-memory.\n- Tracks data in front of ZIP contents as `ZipArchive.getPrefixData()`\n    - Useful for cases like keeping track of the executable header of Jar2Exe archives.\n\n## Usage\n\nMaven dependency:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003esoftware.coley\u003c/groupId\u003e\n    \u003cartifactId\u003elljzip\u003c/artifactId\u003e\n    \u003cversion\u003e${zipVersion}\u003c/version\u003e \u003c!-- See release page for latest version --\u003e\n\u003c/dependency\u003e\n```\n\nGradle dependency:\n```groovy\nimplementation group: 'software.coley', name: 'lljzip', version: zipVersion\nimplementation \"software.coley:lljzip:${zipVersion}\"\n```\n\nBasic usage:\n```java\n// ZipIO offers a number of different utility calls for using different ZipReader implementations\nZipArchive archive = ZipIO.readJvm(path);\n\n// Local files have the actual file data/bytes.\n// These entries mirror data also declared in central directory entries.\nList\u003cLocalFileHeader\u003e localFiles = archive.getLocalFiles();\nfor (LocalFileHeader localFile : localFiles) {\n    // Data model mirrors how a byte-buffer works.\n    ByteData data = localFile.getFileData();\n    \n    // You can extract the data to raw byte[]\n    byte[] decompressed = ZipCompressions.decompress(localFile);\n    \n    // Or do so with a specific decompressor implementation\n    byte[] decompressed = localFile.decompress(DeflateDecompressor.INSTANCE);\n}\n\n// Typically used for authoritative definitions of properties.\n// Some ZIP logic will ignore properties of 'LocalFileHeader' values and use these instead.\n//  - Try using a hex editor to play around with this idea. Plenty of samples in the test cases to look at.\nList\u003cCentralDirectoryFileHeader\u003e centralDirectories = archive.getCentralDirectories();\n\n// Information about the archive and its contents.\nEndOfCentralDirectory end = archive.getEnd();\n```\n\nFor more detailed example usage see the [tests](src/test/java/software/coley/lljzip).\n\n\u003e How does each `ZipReader` implementation map to standard Java ZIP handling?\n\nIf you're looking to see which implementation models different ways of reading ZIP files in Java, here's a table for reference:\n\n| Java closest equivalent | LL-Java-Zip                                        |\n|-------------------------|----------------------------------------------------|\n| `ZipFile`               | `JvmZipReader` / `ZipIO.readJvm(...)`              |\n| `ZipInputStream`        | `ForwardScanZipReader` / `ZipIO.readStandard(...)` |\n| N/A                     | `NaiveLocalFileZipReader` / `ZipIO.readNaive(...)` |\n\nThere is also a `ZipFile` delegating reader `AdaptingZipReader` but it should primarily be used only for debugging purposes.\n\n## Building\n\nDue to some `sun.misc.Unsafe` hacks _(For faster deflate performance)_, you will get compiler warnings when first opening the project in IntelliJ.\nYou can resolve this by changing the compiler target:\n\n![intellij compiler settings](docs/compiler-settings.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcol-e%2Fll-java-zip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcol-e%2Fll-java-zip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcol-e%2Fll-java-zip/lists"}