I'm working on some code to parse and extract the contents of a zip file. I finally figured out how to deal with nested zip archives (see: Extracting a Zip archive containing nested zip files using Kotlin for more details). However, now I am running into a new issue. I want all the files to be extracted into a single directory regardless of where they were nested. The code I have currently is creating directories for nested files and placing the extracted files there. What can I do to get everything into a single directory without having to shift files around after the function has run?
My code currently looks like:
internal fun File.unzipServiceFile(toPath: String): List<File>
{
val retFiles = mutableListOf<File>()
val stream =ZipInputStream(this.inputStream())
stream.unzipServiceFile( toPath, retFiles)
return retFiles
}
private fun ZipInputStream.unzipServiceFile( toPath: String, files:MutableList<File>) {
var entry = nextEntry
println("Parsing entry $entry")
while( entry != null){
println("entry: " + entry.name)
//if there are nested zip files, we need to extract them
if (entry.name.endsWith(".zip")) {
//we need to go deeper
ZipInputStream(this).unzipServiceFile( toPath, files)
}
else if (entry.name.endsWith(".json") && !entry.isDirectory && !entry.name.startsWith(".") && !entry.name.startsWith(
"_"
)
) {
val file = File("$toPath/${entry.name}")
FileUtils.writeByteArrayToFile(file, readBytes())
files.add(file)
println("Added file ${file.path}")
}
entry = nextEntry
}
println()
}
Additional info:
entry.name
is not just the file name, it may also contain a directory component. If you strip that when creating the output file then everything will be extracted in the same directory.
One way to do it:
val file = File("$toPath/${File(entry.name).name}")