Работа с ZIP-архивами в Kotlin: полное руководство
В современной разработке на Kotlin (JVM) часто возникает необходимость упаковывать или распаковывать файлы. Стандартная библиотека Java предоставляет мощные инструменты для работы с ZIP-форматом через пакет java.util.zip. В этой статье мы подробно разберём, как создавать, читать и модифицировать ZIP-архивы, используя Kotlin и встроенные возможности JVM.
Основные классы для работы с ZIP
Для работы с ZIP-архивами в Kotlin используются следующие классы из java.util.zip:
- ZipOutputStream — для создания новых ZIP-архивов и добавления в них файлов.
- ZipInputStream — для последовательного чтения содержимого архива (потоковый режим).
- ZipFile — для произвольного доступа к записям архива (случайный доступ).
- ZipEntry — представляет отдельную запись (файл или директорию) внутри архива.
Все эти классы входят в стандартную библиотеку JDK, поэтому никаких дополнительных зависимостей не требуется.
Создание ZIP-архива
Для создания архива используется ZipOutputStream, который оборачивает FileOutputStream. Каждый файл добавляется через ZipEntry.
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
fun createZipArchive(sourceDir: String, zipFilePath: String) {
val dir = File(sourceDir)
val files = dir.listFiles() ?: return
ZipOutputStream(FileOutputStream(zipFilePath)).use { zos ->
for (file in files) {
if (file.isFile) {
// Создаём запись с именем файла
val entry = ZipEntry(file.name)
zos.putNextEntry(entry)
// Копируем содержимое файла
FileInputStream(file).use { fis ->
fis.copyTo(zos)
}
zos.closeEntry()
}
}
}
println("Архив создан: $zipFilePath")
}
// Пример вызова
fun main() {
createZipArchive("/path/to/source", "/path/to/archive.zip")
}
Распаковка ZIP-архива
Распаковка выполняется через ZipInputStream. Считываем каждую запись и восстанавливаем файлы на диск.
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.zip.ZipInputStream
fun extractZipArchive(zipFilePath: String, outputDir: String) {
val outputFolder = File(outputDir).also { it.mkdirs() }
ZipInputStream(FileInputStream(zipFilePath)).use { zis ->
var entry = zis.nextEntry
while (entry != null) {
val fileName = entry.name
val outputFile = File(outputFolder, fileName)
// Создаём родительские директории, если нужно
outputFile.parentFile?.mkdirs()
// Распаковываем только файлы (не директории)
if (!entry.isDirectory) {
FileOutputStream(outputFile).use { fos ->
zis.copyTo(fos)
}
}
entry = zis.nextEntry
}
}
println("Архив распакован в: $outputDir")
}
// Пример вызова
fun main() {
extractZipArchive("/path/to/archive.zip", "/path/to/extract")
}
Чтение содержимого архива без распаковки
Для просмотра файлов внутри ZIP без извлечения используйте ZipFile и итерацию по entries().
import java.io.File
import java.util.zip.ZipFile
fun listZipContents(zipFilePath: String) {
ZipFile(File(zipFilePath)).use { zipFile ->
println("Содержимое архива: ${zipFile.name}")
println("Всего записей: ${zipFile.size()}")
zipFile.entries().asSequence().forEach { entry ->
val sizeKB = entry.size / 1024.0
println(" ${if (entry.isDirectory) "[DIR]" else "[FILE]"} ${entry.name} (${"%.1f".format(sizeKB)} KB)")
}
}
}
// Пример вызова
fun main() {
listZipContents("/path/to/archive.zip")
}
Добавление файлов в существующий архив
К сожалению, ZipOutputStream не поддерживает добавление записей в уже существующий архив без его пересоздания. Для этого необходимо сначала распаковать архив, добавить новые файлы и упаковать заново. Однако можно читать архив и записывать его копию с новыми данными.
import java.io.*
import java.util.zip.*
fun addFileToArchive(zipFilePath: String, newFile: File) {
val tempFile = File.createTempFile("temp_archive", ".zip")
// Читаем старый архив и записываем в новый
ZipInputStream(FileInputStream(zipFilePath)).use { zis ->
ZipOutputStream(FileOutputStream(tempFile)).use { zos ->
// К Также в библиотеке
Отправка SMS на Java: обзор API библиотек (Twilio, Nexmo, SMS-шлюзы)
gRPC C++ для C++: полное руководство с примерами
AutoMapper для C# (.NET): полное руководство с примерами
Работа с XML в C# (.NET): полное руководство по парсингу и созданию
Парсинг HTML в C++: библиотеки и примеры для работы с DOM и XPath