Trabajo con archivos ZIP en Kotlin
En el desarrollo moderno con Kotlin (tanto para JVM como para Android), a menudo surge la necesidad de empaquetar archivos en archivos ZIP o extraer datos de ellos. La biblioteca estándar de Java (java.util.zip) proporciona todas las clases necesarias que funcionan perfectamente también en Kotlin. En este artículo, analizaremos en detalle tres operaciones principales: creación de archivos, lectura de contenido y descompresión de archivos.
1. Creación de un archivo ZIP (empaquetado de archivos)
Para crear un archivo se utiliza ZipOutputStream. Cada archivo se agrega como una entrada separada (ZipEntry). Veamos un ejemplo que empaqueta varios archivos en un solo archivo.
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) { // Creamos una entrada con el nombre del archivo val entry = ZipEntry(file.name) zipOut.putNextEntry(entry)
// Leemos el archivo original y escribimos en el archivo 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("Archivo creado: ${archive.absolutePath}")}Observe el uso de .use { ... } — es un cierre seguro de recursos, equivalente a try-with-resources en Java. Si necesita empaquetar archivos de subdirectorios, tendrá que recorrer recursivamente los directorios y guardar las rutas relativas en el nombre de ZipEntry.
2. Lectura del contenido del archivo (visualización de la lista de archivos)
A veces solo es necesario ver qué archivos están dentro del archivo, sin extraerlos. Para esto se utiliza ZipFile o ZipInputStream. La primera opción es más conveniente si el archivo ya existe y no es demasiado grande.
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("Archivo no encontrado") }}El método entries() devuelve una enumeración de todas las entradas. Para cada entrada están disponibles el nombre, tamaño, fecha de modificación y banderas (por ejemplo, si la entrada es un directorio).
3. Descompresión de un archivo ZIP (extracción de archivos)
Para extraer archivos es conveniente usar ZipInputStream. Lee el archivo secuencialmente, entrada por entrada. A continuación se muestra un ejemplo de descompresión completa en una carpeta especificada.
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)
// Creamos los directorios padre si es necesario targetFile.parentFile?.mkdirs()
// Si la entrada es un directorio, simplemente lo creamos if (entry.isDirectory) { targetFile.mkdirs() } else { También en la biblioteca
Trabajo con S3 y almacenamiento en la nube en Swift (iOS/macOS): AWSS3 y Amplify
Trabajo con YAML en C++: bibliotecas yaml-cpp y rapidyaml
Análisis de HTML en C++: Reseña de las bibliotecas Gumbo, MyHTML y htmlcxx