Getting Started¶
This guide covers adding KioArch to a Kotlin Multiplatform or single-platform Gradle build and performing common archive operations.
Gradle Setup¶
KioArch is published to Maven Central under the group ID com.sorrowblue.kioarch.
Basic Usage¶
1. Opening an Archive and Listing Entries¶
KioArch.createReader inspects the leading bytes of the input source, initializes the matching native decoder, and returns an ArchiveReader. Always wrap the reader in a .use { ... } block so native handles and the underlying SeekableSource are closed deterministically.
import com.sorrowblue.kioarch.KioArch
import kotlinx.io.files.Path
val archivePath = Path("path/to/archive.7z")
KioArch.createReader(archivePath).use { reader ->
for (entry in reader.getEntries()) {
val type = if (entry.isDirectory) "DIR " else "FILE"
println("[$type] ${entry.name} (${entry.compressedSize} -> ${entry.size} bytes)")
}
}
Path Normalization
Archive entry names (ArchiveEntry.name) are automatically normalized to use forward slashes (/) regardless of whether the archive was created on Windows or Unix.
2. Streaming an Entry into a Sink¶
To extract large files without allocating the entire uncompressed payload in heap memory, stream the entry into any kotlinx.io.Sink using ArchiveReader.extractEntry or the ArchiveEntry.extract extension:
import com.sorrowblue.kioarch.KioArch
import com.sorrowblue.kioarch.extract
import kotlinx.io.buffered
import kotlinx.io.files.Path
import kotlinx.io.files.SystemFileSystem
KioArch.createReader(Path("archive.zip")).use { reader ->
val target = reader.getEntries().first { !it.isDirectory && it.name == "docs/manual.pdf" }
SystemFileSystem.sink(Path("output/manual.pdf")).buffered().use { sink ->
with(reader) {
target.extract(sink)
}
sink.flush()
}
}
3. Extracting Small Entries to a ByteArray¶
For small configuration files, manifests, or thumbnails that fit comfortably in memory, use extractToByteArray:
import com.sorrowblue.kioarch.KioArch
import com.sorrowblue.kioarch.extractToByteArray
import kotlinx.io.files.Path
val jsonText: String = KioArch.createReader(Path("bundle.tar.gz")).use { reader ->
val entry = reader.getEntries().first { it.name == "manifest.json" }
with(reader) {
entry.extractToByteArray().decodeToString()
}
}
Error Handling¶
All native and I/O failures during header parsing or extraction are translated into subclasses of the sealed ArchiveException hierarchy:
| Exception Class | Cause |
|---|---|
ArchiveUnsupportedException |
Unrecognized magic signature or unsupported compression method (such as encrypted headers). |
ArchiveCorruptedException |
Truncated archive, invalid header structure, or CRC32 / bitstream verification failure. |
ArchiveIOException |
Underlying SeekableSource read/seek failure or Sink write error. |
ArchiveInvalidException |
Invalid entry index or illegal operation on a closed ArchiveReader. |
ArchiveOutOfMemoryException |
Native decoder dictionary or heap allocation failure. |
import com.sorrowblue.kioarch.ArchiveCorruptedException
import com.sorrowblue.kioarch.ArchiveException
import com.sorrowblue.kioarch.ArchiveUnsupportedException
import com.sorrowblue.kioarch.KioArch
try {
KioArch.createReader(rawBytes).use { reader ->
// Inspect or extract entries
}
} catch (e: ArchiveUnsupportedException) {
println("Unsupported archive format: ${e.message}")
} catch (e: ArchiveCorruptedException) {
println("Archive is damaged or incomplete: ${e.message}")
} catch (e: ArchiveException) {
println("Extraction failed: ${e.message}")
}