I'm working on an application that needs to extract a zip archive of json documents into a folder. The problem I'm encountering is that sometimes the archive contains nested zip files. My current code looks like this:
fun File.unzipServiceFile(toPath: String): List<File>
{
val retFiles = mutableListOf<File>()
ZipFile(this).use { zipFile ->
zipFile.entries().asSequence().forEach { zipEntry ->
zipFile.getInputStream(zipEntry).use { input ->
//if there are nested zip files, we need to extract them
if (zipEntry.name.endsWith(".zip")) {
//we need to go deeper
}
else if (zipEntry.name.endsWith(".json") && !zipEntry.isDirectory && !zipEntry.name.startsWith(".") && !zipEntry.name.startsWith(
"_"
)
) {
val file = File("$toPath/${zipEntry.name}")
FileUtils.writeByteArrayToFile(file, input.readBytes())
retFiles.add(file)
}
}
}
}
return retFiles
}
I don't actually want to write the nested zip files to a folder since I would then have to clean them out of the directory. I simply want to extract the contents, or continue recursing if there are additional layers of nesting. Any idea how I could go about doing this?
You can unzip a File
by using a ZipFile
instance, but you can also unzip the contents of an InputStream
by using an instance of ZipInputStream
:
zipFile.getInputStream(zipEntry).use { input ->
//if there are nested zip files, we need to extract them
if (zipEntry.name.endsWith(".zip")) {
ZipInputStream(input).use { zipStream ->
val nestedZipEntry: ZipEntry = zipStream.nextEntry
// ...
}
} else if ...
}
See here if you need additional help unzipping from a ZipInputStream: How to read file from ZIP using InputStream?