I'm trying to create a zip file in Kotlin. this is the code:
fun main(args: Array<String>) {
var files: Array<String> = arrayOf("/home/matte/theres_no_place.png", "/home/matte/vladstudio_the_moon_and_the_ocean_1920x1440_signed.jpg")
var out = ZipOutputStream(BufferedOutputStream(FileOutputStream("/home/matte/Desktop/test.zip")))
var data = ByteArray(1024)
for (file in files) {
var fi = FileInputStream(file)
var origin = BufferedInputStream(fi)
var entry = ZipEntry(file.substring(file.lastIndexOf("/")))
out.putNextEntry(entry)
origin.buffered(1024).reader().forEachLine {
out.write(data)
}
origin.close()
}
out.close()}
the zip file is created, but the files inside are corrupt!
If you use Kotlin's
IOStreams.copyTo()
extension, it will do the copying work for you, and that ended up working for me.So replace this:
With this:
I also had issues with the
ZipEntry
having a leading slash, but that could just be because I'm on Windows.Note: I didn't end up needing to call
closeEntry()
to get this to work but it is recommended.1) You are writing an empty byte array to the
out
for each line of an input file.2) There is no need in
BufferedReader
because it is enough to read and write bytes instead of lines (which would lead the unpacked content not to be matched with the original).3) All streams should be closed in the case of exceptions. Use method
use
like try-with-resources in java.4)
val
insteadvar
there possible5) Don't use absolute paths except for the quick test snippets.
6) This snippet is not in idiomatic way for Kotlin (see the Todd's answer)
So this is how it should work (though in the Java way):
EDIT: I've ran this snippet with my files and it worked OK.
I did a mix:
It works perfectly!
Here is a solution working with subfolders: