Working with ZIP Archives in Kotlin: Creation, Reading, and Extraction

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with ZIP Archives in Kotlin



In modern Kotlin development (both for JVM and Android), there is often a need to package files into ZIP archives or extract data from them. The standard Java library (java.util.zip) provides all the necessary classes that work perfectly in Kotlin as well. In this article, we will cover three main operations in detail: creating an archive, reading its contents, and extracting files.



1. Creating a ZIP Archive (packing files)



To create an archive, ZipOutputStream is used. Each file is added as a separate entry (ZipEntry). Let's look at an example that packs several files into a single archive.



import java.io.Fileimport java.io.FileInputStreamimport java.io.FileOutputStreamimport java.util.zip.ZipEntryimport java.util.zip.ZipOutputStream

fun createZip( filesToZip: List<File>, outputZipFile: File) { ZipOutputStream(FileOutputStream(outputZipFile)).use { zipOut -> for (file in filesToZip) { // Create an entry with the file name val entry = ZipEntry(file.name) zipOut.putNextEntry(entry)

// Read the source file and write to the archive FileInputStream(file).use { fis -> fis.copyTo(zipOut) } zipOut.closeEntry() } }}

fun main() { val files = listOf( File("document.txt"), File("image.png"), File("data.json") ) val archive = File("my_archive.zip") createZip(files, archive) println("Archive created: ${archive.absolutePath}")}


Note the use of .use { ... } — this is safe resource closing, equivalent to try-with-resources in Java. If you need to pack files from subdirectories, you will have to recursively traverse directories and preserve relative paths in the ZipEntry name.



2. Reading Archive Contents (viewing the file list)



Sometimes you only need to see which files are inside the archive without extracting them. For this, ZipFile or ZipInputStream is used. The first option is more convenient if the archive already exists and is not too large.



import java.io.Fileimport java.util.zip.ZipFile

fun listZipContent(zipFile: File) { ZipFile(zipFile).use { zip -> val entries = zip.entries() while (entries.hasMoreElements()) { val entry = entries.nextElement() println("${entry.name} (${entry.size} bytes)") } }}

fun main() { val archive = File("my_archive.zip") if (archive.exists()) { listZipContent(archive) } else { println("File not found") }}


The entries() method returns an enumeration of all entries. For each entry, the name, size, modification date, and flags (e.g., whether the entry is a directory) are available.



3. Extracting a ZIP Archive (file extraction)



For extracting files, it is convenient to use ZipInputStream. It reads the archive sequentially, entry by entry. Below is an example of a full extraction into a specified folder.



import java.io.Fileimport java.io.FileInputStreamimport java.io.FileOutputStreamimport java.util.zip.ZipInputStream

fun extractZip( zipFile: File, outputDir: File) { if (!outputDir.exists()) { outputDir.mkdirs() }

ZipInputStream(FileInputStream(zipFile)).use { zis -> var entry = zis.nextEntry while (entry != null) { val targetFile = File(outputDir, entry.name)

// Create parent directories if needed targetFile.parentFile?.mkdirs()

// If the entry is a directory, just create it if (entry.isDirectory) { targetFile.mkdirs() } else {

Recommendations