Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Zip/Unzip functions in Kotlin
object ZipManager {
fun zip(files: List<String>, outputStream: OutputStream): Boolean = try {
ZipOutputStream(BufferedOutputStream(outputStream)).use { stream ->
for (file in files) {
BufferedInputStream(FileInputStream(File(file))).use { origin ->
stream.putNextEntry(ZipEntry(file.substring(file.lastIndexOf("/") + 1)))
origin.copyTo(stream)
}
}
}
true
} catch (ignored: Exception) {
false
}
fun unzip(inputStream: InputStream, destination: String): Boolean = try {
File(destination).let { file -> file.isDirectory.ifFalse { file.mkdirs() } }
ZipInputStream(BufferedInputStream(inputStream)).use { stream ->
stream.asIterable().forEach { zipEntry ->
val path = "$destination${if (destination.endsWith(File.separator)) "" else File.separator}${zipEntry.name}"
when {
zipEntry.isDirectory -> File(path).let { file -> file.isDirectory.ifFalse(file::mkdirs) }
else -> BufferedOutputStream(FileOutputStream(path)).use { outputStream -> stream.copyTo(outputStream) }
}
}
}
true
} catch (ignored: Exception) {
false
}
fun list(inputStream: InputStream): List<String> = try {
ZipInputStream(inputStream).use { stream -> stream.asIterable().map { zipEntry -> zipEntry.name } }
} catch (ignored: Exception) {
listOf()
}
}
private fun ZipInputStream.asIterable(): Iterable<ZipEntry> = object : Iterable<ZipEntry> {
override fun iterator(): Iterator<ZipEntry> = ZipIterator(this@asIterable)
}
private class ZipIterator(private val stream: ZipInputStream) : Iterator<ZipEntry> {
private var next: ZipEntry? = null
override fun hasNext(): Boolean {
next = stream.nextEntry
return next != null
}
override fun next(): ZipEntry = next ?: throw NoSuchElementException()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment