2017-09-14 1 views
3

J'essaie de créer un fichier zip dans Kotlin. c'est le code:Créer un fichier ZIP dans 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()} 

le fichier zip est créé, mais les fichiers sont corrompus à l'intérieur!

Répondre

3

Si vous utilisez l'extension IOStreams.copyTo() de Kotlin, il fera le travail de copie pour vous, et cela a fini par fonctionner pour moi.

remplacer donc ceci:

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

Avec ceci:

origin.copyTo(out, 1024) 

J'ai aussi eu des problèmes avec l'ZipEntry ayant une barre oblique, mais qui pourrait être juste parce que je suis sous Windows.

Note: Je n'ai pas eu besoin d'appeler closeEntry() pour que cela fonctionne, mais c'est recommandé.

0

1) Vous écrivez un tableau d'octets vide au out pour chaque ligne d'un fichier d'entrée.

2) Il n'y a pas besoin de BufferedReader car il suffit de lire et d'écrire des octets au lieu de lignes (ce qui conduirait à ce que le contenu décompressé ne corresponde pas à l'original).

3) Tous les flux doivent être fermés dans le cas d'exceptions. Utilisez la méthode use comme try-with-resources dans java.

4) val à la place var il possible

5) Ne pas utiliser des chemins absolus, sauf pour les extraits de tests rapides.

6) Cet extrait n'est pas de manière idiomatiques pour Kotlin (voir la réponse du Todd)

Voilà donc comment cela devrait fonctionner (bien que de la manière 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: J'ai exécuté cet extrait avec mes fichiers et cela a fonctionné correctement.

0

je l'ai fait un mélange:

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

cela fonctionne parfaitement! merci beaucoup aux deux!