Создать файл ZIP в Котлине

Я пытаюсь создать zip-файл в Kotlin. это код:

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()} 

zip-файл создается, но файлы внутри повреждены!

Если вы используете расширение IOStreams.copyTo() Kotlin, оно сделает для вас работу по копированию, и это закончилось для меня работой.

Поэтому замените это:

 origin.buffered(1024).reader().forEachLine { out.write(data) } 

С этим:

 origin.copyTo(out, 1024) 

У меня также были проблемы с ZipEntry с ведущим косой чертой, но это может быть просто из-за того, что я нахожусь в Windows.

Примечание. Мне не нужно было вызвать closeEntry() чтобы заставить это работать, но это рекомендуется.

1) Вы пишете пустой байтовый массив для каждой строки входного файла.

2) В BufferedReader нет необходимости, потому что достаточно читать и писать байты вместо строк (что приведет к тому, что распакованный контент не будет соответствовать оригиналу).

3) Все потоки должны быть закрыты в случае исключений. Использовать метод, например try-with-resources, в java.

4) val вместо var там возможно

5) Не используйте абсолютные пути, за исключением быстрых фрагментов теста.

6) Этот фрагмент не является идиоматическим для Котлина (см. Ответ Тодда)

Так вот как это должно работать (хотя и на Java-пути):

 fun main(args: Array<String>) { val files: Array<String> = arrayOf("/home/matte/theres_no_place.png", "/home/matte/vladstudio_the_moon_and_the_ocean_1920x1440_signed.jpg") ZipOutputStream(BufferedOutputStream(FileOutputStream("/home/matte/Desktop/test.zip"))).use { out -> val data = ByteArray(1024) for (file in files) { FileInputStream(file).use { fi -> BufferedInputStream(fi).use { origin -> val entry = ZipEntry(file) out.putNextEntry(entry) while (true) { val readBytes = origin.read(data) if (readBytes == -1) { break } out.write(data, 0, readBytes) } } } } } } 

EDIT: Я запустил этот фрагмент с моими файлами, и он работал нормально.

я сделал микс:

 fun main(args: Array<String>) { val files: Array<String> = arrayOf("/home/matte/theres_no_place.png", "/home/matte/vladstudio_the_moon_and_the_ocean_1920x1440_signed.jpg") ZipOutputStream(BufferedOutputStream(FileOutputStream("/home/matte/Desktop/test.zip"))).use { out -> for (file in files) { FileInputStream(file).use { fi -> BufferedInputStream(fi).use { origin -> val entry = ZipEntry(file.substring(file.lastIndexOf("/"))) out.putNextEntry(entry) origin.copyTo(out, 1024) } } } } } 

он отлично работает! большое спасибо обоим!