Skip to content

Jojo4GH/kzip

Repository files navigation

Kzip

Maven Central GitHub

Kotlin Multiplatform JVM Platform Linux X64 Platform Linux ARM64 Platform MinGW X64 Platform Android X64 Platform Android ARM64 Platform

A lightweight Kotlin Multiplatform library for reading, writing and modifying ZIP files.

⭐️ Main Features

  • 🗂️ Reading ZIP entries and metadata
  • 🗜️ Easy extraction and compression of files and directories
  • 📝 Modifying existing ZIP files

The kotlin file I/O interface uses kotlinx-io making it compatible with other Kotlin Multiplatform libraries. The JVM implementation uses the standard java.util.zip while the current native implementation uses the lightweight kuba--/zip.

Currently kzip supports the following targets:

  • jvm
  • linuxX64
  • linuxArm64
  • mingwX64
  • androidNativeX64
  • androidNativeArm64

But the following targets are planned (mostly only requiring testing):

  • All Apple targets
  • androidNativeX86
  • androidNativeArm32

More features are planned including support for suspending functions, more access to metadata, more utilities and integrations into other KMP libraries (see also Contributing).

🛠️ Installation

The kzip dependency is available on Maven Central and can be added to your common source set. Just replace $kzipVersion with the latest version.

Gradle - Kotlin DSL
implementation("de.jonasbroeckmann.kzip:kzip:$kzipVersion")
Gradle - Groovy DSL
implementation "de.jonasbroeckmann.kzip:kzip:$kzipVersion"
Maven
<dependencies>
    <dependency>
        <groupId>de.jonasbroeckmann.kzip</groupId>
        <artifactId>kzip</artifactId>
        <version>$kzipVersion</version>
    </dependency>
</dependencies>

🚀 Usage

Reading a ZIP file

val zip = Zip.open(Path("example.zip"))

// Access a specific entry
zip.entry(Path("content.txt")) {
    println("Entry content.txt has size $uncompressedSize")
    println("Entry content.txt has content:")
    println(readToSource().readString())
}

// Access all entries
zip.forEachEntry { entry ->
    println("Entry ${entry.path} has size ${entry.uncompressedSize}")

    if (entry.isDirectory) {
        println("Entry is a directory")
    } else {
        println("Entry is a file with content:")
        println(entry.readToSource().readString())
    }
}

zip.close()

Extracting a ZIP file

Zip.open(Path("example.zip")).use { zip ->
    zip.extractTo(Path("example"))
}

Creating a ZIP file from a directory

Zip.open(
    path = Path("example.zip"),
    mode = Zip.Mode.Write,
    // Optional: Set compression level
    level = Zip.CompressionLevel.BetterCompression
).use { zip ->
    zip.compressFrom(Path("example"))
}

Modifying a ZIP file

val textSource = Buffer().apply { writeString("Hello, World!") }
Zip.open(Path("example.zip"), mode = Zip.Mode.Append).use { zip ->
    // Add a folder
    zip.folderEntry(Path("subfolder"))
    // Add a file from a path
    zip.entryFromPath(Path("compressed.txt"), Path("example.txt"))
    // Add a file from a source
    zip.entryFromSource(Path("hello_world.txt"), textSource)
}
textSource.close()

🚧 Contributing

If you have any ideas, feel free to open an issue or create a pull request.

📄 License

This project is licensed under the MIT License.