在Kotlin中处理ZIP/压缩包:创建、读取和解压

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在Kotlin中处理ZIP/压缩包



在现代Kotlin开发中(无论是针对JVM还是Android),经常需要将文件打包成ZIP压缩包或从中提取数据。标准Java库(java.util.zip)提供了所有必要的类,这些类在Kotlin中也能完美运行。本文将详细讲解三种主要操作:创建压缩包、读取内容和解压文件。



1. 创建ZIP压缩包(打包文件)



创建压缩包使用ZipOutputStream。每个文件作为单独的条目(ZipEntry)添加。请看一个将多个文件打包到一个压缩包中的示例。



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) { // 创建以文件命名的条目 val entry = ZipEntry(file.name) zipOut.putNextEntry(entry)

// 读取源文件并写入压缩包 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.absolutePath}")}


请注意使用.use { ... }——这是安全的资源关闭方式,相当于Java中的try-with-resources。如果需要打包子目录中的文件,则必须递归遍历目录并在ZipEntry名称中保留相对路径。



2. 读取压缩包内容(查看文件列表)



有时只需要查看压缩包内有哪些文件,而无需解压它们。为此,可以使用ZipFile或ZipInputStream。如果压缩包已存在且体积不大,第一种方式更方便。



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} 字节)") } }}

fun main() { val archive = File("my_archive.zip") if (archive.exists()) { listZipContent(archive) } else { println("文件未找到") }}


entries()方法返回所有条目的枚举。每个条目都可以获取名称、大小、修改日期和标志(例如,该条目是否为目录)。



3. 解压ZIP压缩包(提取文件)



解压文件时,使用ZipInputStream很方便。它会顺序读取压缩包,逐条记录处理。下面是一个将压缩包完全解压到指定文件夹的示例。



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)

// 如有需要,创建父目录 targetFile.parentFile?.mkdirs()

// 如果条目是目录,直接创建它 if (entry.isDirectory) { targetFile.mkdirs() } else {

推荐