
ZIP input/output streams with Java-compatible byte-array streams, DEFLATE via zlib, adapters for common I/O libraries, and comprehensive ZipEntry metadata plus streaming APIs.
Kotlin Multiplatform ZIP and GZIP library for JVM and iOS targets.
Provides ByteArrayInputStream, ByteArrayOutputStream, ZipInputStream, ZipOutputStream, GzipInputStream, and GzipOutputStream with a common API across platforms. On JVM, the implementations delegate to java.io and java.util.zip. On iOS/Native, they are pure Kotlin implementations using platform.zlib for DEFLATE compression and decompression.
| Artifact | Description |
|---|---|
no.synth:kmp-zip |
Core I/O, ZIP, and GZIP streams |
no.synth:kmp-zip-kotlinx |
kotlinx-io Source/Sink adapters (both directions) for the core streams |
no.synth:kmp-zip-okio |
OkIO BufferedSource/BufferedSink/Source/Sink adapters (both directions) for the core streams |
Published on Maven Central. No special repository configuration needed.
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("no.synth:kmp-zip:0.8.0")
// Optional: kotlinx-io adapters
implementation("no.synth:kmp-zip-kotlinx:0.8.0")
// Optional: OkIO adapters
implementation("no.synth:kmp-zip-okio:0.8.0")
}
}
}
}| Type | Description |
|---|---|
InputStream |
Abstract class — read(), read(ByteArray, off, len), available(), skip(), close(), etc. |
OutputStream |
Abstract class — write(Int), write(ByteArray, off, len), flush(), close()
|
ByteArrayInputStream |
Reads from a ByteArray. Full Java-compatible API. |
ByteArrayOutputStream |
Auto-growing buffer with toByteArray(), size(), reset(), writeTo()
|
InputStream.readBytes() |
Extension that reads all remaining bytes |
| Type | Description |
|---|---|
ZipInputStream(InputStream) |
Reads ZIP entries — nextEntry, closeEntry(), read(), readBytes()
|
ZipInputStream(ByteArray) |
Convenience factory |
ZipOutputStream(OutputStream) |
Writes ZIP entries — putNextEntry(), closeEntry(), write(), finish(), setMethod(), setLevel()
|
ZipEntry |
Entry metadata — name, size, compressedSize, crc, method, isDirectory, time, comment, extra
|
ZipConstants |
STORED = 0, DEFLATED = 8
|
| Type | Description |
|---|---|
GzipInputStream(InputStream) |
Decompresses a GZIP stream — read(), available(), close()
|
GzipInputStream(ByteArray) |
Convenience factory |
GzipOutputStream(OutputStream) |
Compresses data in GZIP format — write(), finish(), flush(), close()
|
| Type | Description |
|---|---|
SourceInputStream(Source) |
Wraps a kotlinx-io Source as an InputStream
|
SinkOutputStream(Sink) |
Wraps a kotlinx-io Sink as an OutputStream
|
InputStreamSource(InputStream) |
Wraps an InputStream as a kotlinx-io RawSource
|
OutputStreamSink(OutputStream) |
Wraps an OutputStream as a kotlinx-io RawSink
|
Source.asInputStream() |
Extension shorthand |
Sink.asOutputStream() |
Extension shorthand |
InputStream.asSource() |
Extension shorthand |
OutputStream.asSink() |
Extension shorthand |
ZipInputStream(Source) |
Factory — creates a ZipInputStream from a Source
|
ZipOutputStream(Sink) |
Factory — creates a ZipOutputStream from a Sink
|
GzipInputStream(Source) |
Factory — creates a GzipInputStream from a Source
|
GzipOutputStream(Sink) |
Factory — creates a GzipOutputStream from a Sink
|
| Type | Description |
|---|---|
SourceInputStream(BufferedSource) |
Wraps an OkIO BufferedSource as an InputStream
|
SinkOutputStream(BufferedSink) |
Wraps an OkIO BufferedSink as an OutputStream
|
InputStreamSource(InputStream) |
Wraps an InputStream as an OkIO Source
|
OutputStreamSink(OutputStream) |
Wraps an OutputStream as an OkIO Sink
|
BufferedSource.asInputStream() |
Extension shorthand |
BufferedSink.asOutputStream() |
Extension shorthand |
InputStream.asSource() |
Extension shorthand |
OutputStream.asSink() |
Extension shorthand |
ZipInputStream(BufferedSource) |
Factory — creates a ZipInputStream from a BufferedSource
|
ZipOutputStream(BufferedSink) |
Factory — creates a ZipOutputStream from a BufferedSink
|
GzipInputStream(BufferedSource) |
Factory — creates a GzipInputStream from a BufferedSource
|
GzipOutputStream(BufferedSink) |
Factory — creates a GzipOutputStream from a BufferedSink
|
ZipInputStream(zipBytes).use { zis ->
while (true) {
val entry = zis.nextEntry ?: break
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}
}val buf = ByteArrayOutputStream()
ZipOutputStream(buf).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello, world!".encodeToByteArray())
zos.closeEntry()
}
val zipBytes = buf.toByteArray()// Compress
val buf = ByteArrayOutputStream()
GzipOutputStream(buf).use { gzos ->
gzos.write("Hello, world!".encodeToByteArray())
}
val gzipped = buf.toByteArray()
// Decompress
val text = GzipInputStream(gzipped).use { gzis ->
gzis.readBytes().decodeToString()
}import kotlinx.io.Buffer
import no.synth.kmpzip.kotlinx.ZipInputStream
import no.synth.kmpzip.kotlinx.ZipOutputStream
val buffer = Buffer()
// Write
ZipOutputStream(buffer).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello from kotlinx-io!".encodeToByteArray())
zos.closeEntry()
}
// Read
ZipInputStream(buffer).use { zis ->
val entry = zis.nextEntry ?: error("Expected entry")
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}import okio.Buffer
import no.synth.kmpzip.okio.ZipInputStream
import no.synth.kmpzip.okio.ZipOutputStream
val buffer = Buffer()
// Write
ZipOutputStream(buffer).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello from OkIO!".encodeToByteArray())
zos.closeEntry()
}
// Read
ZipInputStream(buffer).use { zis ->
val entry = zis.nextEntry ?: error("Expected entry")
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}The InputStream.asSource() adapter lets you read a ZIP entry through a Source, which is useful
for streaming deserialization (e.g. kotlinx-serialization's decodeFromBufferedSource).
OkIO:
import okio.buffer
import no.synth.kmpzip.okio.ZipInputStream
import no.synth.kmpzip.okio.asSource
ZipInputStream(source).use { zis ->
val entry = zis.nextEntry
if (entry != null) {
val entrySource = zis.asSource().buffer()
// Stream directly from the ZIP entry — e.g. Json.decodeFromBufferedSource(serializer, entrySource)
println("${entry.name}: ${entrySource.readUtf8()}")
}
}kotlinx-io:
import kotlinx.io.buffered
import kotlinx.io.readString
import no.synth.kmpzip.kotlinx.ZipInputStream
import no.synth.kmpzip.kotlinx.asSource
ZipInputStream(source).use { zis ->
val entry = zis.nextEntry
if (entry != null) {
val entrySource = zis.asSource().buffered()
// Stream directly from the ZIP entry — e.g. Json.decodeFromBufferedSource(serializer, entrySource)
println("${entry.name}: ${entrySource.readString()}")
}
}The OutputStream.asSink() adapter lets you write into
a ZIP entry through a Sink, which is useful for streaming serialization (e.g. kotlinx-serialization's
encodeToSink).
OkIO:
import okio.buffer
import no.synth.kmpzip.okio.ZipOutputStream
import no.synth.kmpzip.okio.asSink
ZipOutputStream(sink).use { zos ->
zos.putNextEntry(ZipEntry("data.json"))
val entrySink = zos.asSink().buffer()
// Stream directly into the ZIP entry — e.g. Json.encodeToSink(serializer, value, entrySink)
entrySink.writeUtf8("""{"hello": "world"}""")
entrySink.flush()
zos.closeEntry()
}kotlinx-io:
import kotlinx.io.buffered
import kotlinx.io.writeString
import no.synth.kmpzip.kotlinx.ZipOutputStream
import no.synth.kmpzip.kotlinx.asSink
ZipOutputStream(sink).use { zos ->
zos.putNextEntry(ZipEntry("data.json"))
val entrySink = zos.asSink().buffered()
// Stream directly into the ZIP entry — e.g. Json.encodeToSink(serializer, value, entrySink)
entrySink.writeString("""{"hello": "world"}""")
entrySink.flush()
zos.closeEntry()
}Requires JDK 21 and Xcode (for iOS targets).
./gradlew build # Full build
./gradlew jvmTest # JVM tests
./gradlew iosSimulatorArm64Test # iOS simulator testsTagging a release triggers the GitHub Actions workflow to publish to Maven Central:
git tag v0.8.0
git push origin v0.8.0Kotlin Multiplatform ZIP and GZIP library for JVM and iOS targets.
Provides ByteArrayInputStream, ByteArrayOutputStream, ZipInputStream, ZipOutputStream, GzipInputStream, and GzipOutputStream with a common API across platforms. On JVM, the implementations delegate to java.io and java.util.zip. On iOS/Native, they are pure Kotlin implementations using platform.zlib for DEFLATE compression and decompression.
| Artifact | Description |
|---|---|
no.synth:kmp-zip |
Core I/O, ZIP, and GZIP streams |
no.synth:kmp-zip-kotlinx |
kotlinx-io Source/Sink adapters (both directions) for the core streams |
no.synth:kmp-zip-okio |
OkIO BufferedSource/BufferedSink/Source/Sink adapters (both directions) for the core streams |
Published on Maven Central. No special repository configuration needed.
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("no.synth:kmp-zip:0.8.0")
// Optional: kotlinx-io adapters
implementation("no.synth:kmp-zip-kotlinx:0.8.0")
// Optional: OkIO adapters
implementation("no.synth:kmp-zip-okio:0.8.0")
}
}
}
}| Type | Description |
|---|---|
InputStream |
Abstract class — read(), read(ByteArray, off, len), available(), skip(), close(), etc. |
OutputStream |
Abstract class — write(Int), write(ByteArray, off, len), flush(), close()
|
ByteArrayInputStream |
Reads from a ByteArray. Full Java-compatible API. |
ByteArrayOutputStream |
Auto-growing buffer with toByteArray(), size(), reset(), writeTo()
|
InputStream.readBytes() |
Extension that reads all remaining bytes |
| Type | Description |
|---|---|
ZipInputStream(InputStream) |
Reads ZIP entries — nextEntry, closeEntry(), read(), readBytes()
|
ZipInputStream(ByteArray) |
Convenience factory |
ZipOutputStream(OutputStream) |
Writes ZIP entries — putNextEntry(), closeEntry(), write(), finish(), setMethod(), setLevel()
|
ZipEntry |
Entry metadata — name, size, compressedSize, crc, method, isDirectory, time, comment, extra
|
ZipConstants |
STORED = 0, DEFLATED = 8
|
| Type | Description |
|---|---|
GzipInputStream(InputStream) |
Decompresses a GZIP stream — read(), available(), close()
|
GzipInputStream(ByteArray) |
Convenience factory |
GzipOutputStream(OutputStream) |
Compresses data in GZIP format — write(), finish(), flush(), close()
|
| Type | Description |
|---|---|
SourceInputStream(Source) |
Wraps a kotlinx-io Source as an InputStream
|
SinkOutputStream(Sink) |
Wraps a kotlinx-io Sink as an OutputStream
|
InputStreamSource(InputStream) |
Wraps an InputStream as a kotlinx-io RawSource
|
OutputStreamSink(OutputStream) |
Wraps an OutputStream as a kotlinx-io RawSink
|
Source.asInputStream() |
Extension shorthand |
Sink.asOutputStream() |
Extension shorthand |
InputStream.asSource() |
Extension shorthand |
OutputStream.asSink() |
Extension shorthand |
ZipInputStream(Source) |
Factory — creates a ZipInputStream from a Source
|
ZipOutputStream(Sink) |
Factory — creates a ZipOutputStream from a Sink
|
GzipInputStream(Source) |
Factory — creates a GzipInputStream from a Source
|
GzipOutputStream(Sink) |
Factory — creates a GzipOutputStream from a Sink
|
| Type | Description |
|---|---|
SourceInputStream(BufferedSource) |
Wraps an OkIO BufferedSource as an InputStream
|
SinkOutputStream(BufferedSink) |
Wraps an OkIO BufferedSink as an OutputStream
|
InputStreamSource(InputStream) |
Wraps an InputStream as an OkIO Source
|
OutputStreamSink(OutputStream) |
Wraps an OutputStream as an OkIO Sink
|
BufferedSource.asInputStream() |
Extension shorthand |
BufferedSink.asOutputStream() |
Extension shorthand |
InputStream.asSource() |
Extension shorthand |
OutputStream.asSink() |
Extension shorthand |
ZipInputStream(BufferedSource) |
Factory — creates a ZipInputStream from a BufferedSource
|
ZipOutputStream(BufferedSink) |
Factory — creates a ZipOutputStream from a BufferedSink
|
GzipInputStream(BufferedSource) |
Factory — creates a GzipInputStream from a BufferedSource
|
GzipOutputStream(BufferedSink) |
Factory — creates a GzipOutputStream from a BufferedSink
|
ZipInputStream(zipBytes).use { zis ->
while (true) {
val entry = zis.nextEntry ?: break
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}
}val buf = ByteArrayOutputStream()
ZipOutputStream(buf).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello, world!".encodeToByteArray())
zos.closeEntry()
}
val zipBytes = buf.toByteArray()// Compress
val buf = ByteArrayOutputStream()
GzipOutputStream(buf).use { gzos ->
gzos.write("Hello, world!".encodeToByteArray())
}
val gzipped = buf.toByteArray()
// Decompress
val text = GzipInputStream(gzipped).use { gzis ->
gzis.readBytes().decodeToString()
}import kotlinx.io.Buffer
import no.synth.kmpzip.kotlinx.ZipInputStream
import no.synth.kmpzip.kotlinx.ZipOutputStream
val buffer = Buffer()
// Write
ZipOutputStream(buffer).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello from kotlinx-io!".encodeToByteArray())
zos.closeEntry()
}
// Read
ZipInputStream(buffer).use { zis ->
val entry = zis.nextEntry ?: error("Expected entry")
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}import okio.Buffer
import no.synth.kmpzip.okio.ZipInputStream
import no.synth.kmpzip.okio.ZipOutputStream
val buffer = Buffer()
// Write
ZipOutputStream(buffer).use { zos ->
zos.putNextEntry(ZipEntry("hello.txt"))
zos.write("Hello from OkIO!".encodeToByteArray())
zos.closeEntry()
}
// Read
ZipInputStream(buffer).use { zis ->
val entry = zis.nextEntry ?: error("Expected entry")
println("${entry.name}: ${zis.readBytes().decodeToString()}")
}The InputStream.asSource() adapter lets you read a ZIP entry through a Source, which is useful
for streaming deserialization (e.g. kotlinx-serialization's decodeFromBufferedSource).
OkIO:
import okio.buffer
import no.synth.kmpzip.okio.ZipInputStream
import no.synth.kmpzip.okio.asSource
ZipInputStream(source).use { zis ->
val entry = zis.nextEntry
if (entry != null) {
val entrySource = zis.asSource().buffer()
// Stream directly from the ZIP entry — e.g. Json.decodeFromBufferedSource(serializer, entrySource)
println("${entry.name}: ${entrySource.readUtf8()}")
}
}kotlinx-io:
import kotlinx.io.buffered
import kotlinx.io.readString
import no.synth.kmpzip.kotlinx.ZipInputStream
import no.synth.kmpzip.kotlinx.asSource
ZipInputStream(source).use { zis ->
val entry = zis.nextEntry
if (entry != null) {
val entrySource = zis.asSource().buffered()
// Stream directly from the ZIP entry — e.g. Json.decodeFromBufferedSource(serializer, entrySource)
println("${entry.name}: ${entrySource.readString()}")
}
}The OutputStream.asSink() adapter lets you write into
a ZIP entry through a Sink, which is useful for streaming serialization (e.g. kotlinx-serialization's
encodeToSink).
OkIO:
import okio.buffer
import no.synth.kmpzip.okio.ZipOutputStream
import no.synth.kmpzip.okio.asSink
ZipOutputStream(sink).use { zos ->
zos.putNextEntry(ZipEntry("data.json"))
val entrySink = zos.asSink().buffer()
// Stream directly into the ZIP entry — e.g. Json.encodeToSink(serializer, value, entrySink)
entrySink.writeUtf8("""{"hello": "world"}""")
entrySink.flush()
zos.closeEntry()
}kotlinx-io:
import kotlinx.io.buffered
import kotlinx.io.writeString
import no.synth.kmpzip.kotlinx.ZipOutputStream
import no.synth.kmpzip.kotlinx.asSink
ZipOutputStream(sink).use { zos ->
zos.putNextEntry(ZipEntry("data.json"))
val entrySink = zos.asSink().buffered()
// Stream directly into the ZIP entry — e.g. Json.encodeToSink(serializer, value, entrySink)
entrySink.writeString("""{"hello": "world"}""")
entrySink.flush()
zos.closeEntry()
}Requires JDK 21 and Xcode (for iOS targets).
./gradlew build # Full build
./gradlew jvmTest # JVM tests
./gradlew iosSimulatorArm64Test # iOS simulator testsTagging a release triggers the GitHub Actions workflow to publish to Maven Central:
git tag v0.8.0
git push origin v0.8.0