在Kotlin中创建文件ZIP
问题描述:
我正在尝试在Kotlin中创建一个zip文件。 这是代码:在Kotlin中创建文件ZIP
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文件被创建,但里面的文件已损坏!
答
如果您使用Kotlin的IOStreams.copyTo()
扩展名,它将为您完成复制工作,并最终为我工作。
所以替换此:
origin.buffered(1024).reader().forEachLine {
out.write(data)
}
有了这个:
origin.copyTo(out, 1024)
我也有问题,与具有斜线的ZipEntry
,但是这可能仅仅是因为我是在Windows上。
注意:我并没有最终需要致电closeEntry()
才能使其工作,但建议您使用此工具。
答
1)您正在为输入文件的每一行写入一个空字节数组到out
。
2)BufferedReader
没有必要,因为它足以读取和写入字节而不是行(这将导致解压缩的内容不能与原始内容匹配)。
3)在例外的情况下,所有流都应该关闭。使用方法use
像java中的try-with-resources。
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)
}
}
}
}
}
}
编辑:我已经用我的文件运行了这个代码片段,它工作正常。
答
我做了一个组合:
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)
}
}
}
}
}
它完美的作品! 非常感谢!