Java NIO ZipFileSystem:" zip END header not found " lors de la création du système de fichiers


Je demande ceci ici parce que googler cette erreur ne me donne que des coups sur l'écriture d'un fichier zip, alors que j'essaie seulement de le lire.
J'ai un test unitaire où j'essaie de tester le code de production suivant:

Map<String, String> zipProps = new HashMap<>();
URI zipUri = URI.create("jar:file:" + itemZipPath.toString());
try (FileSystem zipfiles = FileSystems.newFileSystem(zipUri, zipProps)) {
   // do stuff...
} catch (IOException e) {
   // log an error
}

Cependant, cela échoue sur la ligne contenant l'essai:

java.util.zip.ZipError: zip END header not found
at com.sun.nio.zipfs.ZipFileSystem.zerror(ZipFileSystem.java:1605)
at com.sun.nio.zipfs.ZipFileSystem.findEND(ZipFileSystem.java:1021)
at com.sun.nio.zipfs.ZipFileSystem.initCEN(ZipFileSystem.java:1030)
at com.sun.nio.zipfs.ZipFileSystem.<init>(ZipFileSystem.java:130)
at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:117)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)
at com.company.PageCommandHandler$ProvisioningSteps.getItemModel(PageCommandHandler.java:105)

J'ai essayé de créer le fichier zip en utilisant l'utilitaire zip d'OSX et en utilisant jar cvf mais les deux échouent (la sortie de file <filename> diffère légèrement cependant). Toutes les informations sur cette erreur que je peux trouver concernent pour créer un fichier zipfile en utilisant Java NIO, mais comme vous pouvez le voir, je ne fais qu'une lecture (vérifiant la présence d'un certain fichier dans le ZIP pour l'instant). Des réflexions sur ce qui ne va pas ici?

Author: Ton van Bart, 2016-05-24

3 answers

J'ai rencontré exactement la même erreur. Java 8. La raison en était que, par erreur, j'ai créé un fichier vide, pas seulement un objet:

File zipFile = new File(path);
zipFile.createNewFile();

An a ensuite passé ce chemin à

URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

Pour le réparer, je n'ai pas créé de fichier lui-même, j'ai seulement créé un objet File:

File zipFile = new File(path);
URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

Pour le rendre plus fiable, je proposerais de supprimer d'abord le fichier s'il existe:

File zipFile = new File(path);
//Caused by: java.util.zip.ZipError: zip END header not found
if (zipFile.exists()){
    try {
        Files.delete(Paths.get(zipFile.getAbsolutePath()));
    } catch (IOException e) {
        throw new IllegalStateException(
                "Could not delete file.", e);
    }
}
...
URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

, Probablement, dans certains cas, la solution avec la suppression du fichier n'est pas acceptable. Par exemple, si vous ajoutez au même fichier zip plusieurs entrée. Mais dans mon cas d'utilisation, c'est OK.

 2
Author: Alexandr, 2018-01-25 13:59:43

J'ai essayé d'utiliser le ZipInputStream normal et les classes associées, mais j'ai continué à avoir des problèmes, donc le problème ne semblait pas lié à NIO. Un de mes collègues a trouvé cette question sur SO: L'extraction d'un fichier compressé à partir de ResourceStream génère une erreur "Longueurs de bloc stockées non valides"

J'ai donc essayé d'ajouter cet extrait à mon pom.xml aussi bien:

<properties>
    <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
</properties>

Après cela, tous les problèmes ont disparu et tous mes tests sont devenus verts. Je ne suis pas revenu à NIO car j'étais assez heureux d'arriver à un solution de travail, mais je suis sûr que cela résoudrait également le problème sur NIO.

Posté ici dans l'espoir que cela aide quelqu'un ayant le même problème un jour.

 0
Author: Ton van Bart, 2017-05-23 12:15:56

Peut-être que vous n'avez pas utilisé la classe ZipInputStream ? Qu'est-ce que la ligne 326 ?

Voici un exemple pour décompresser et extraire des fichiers zip. http://www.oracle.com/technetwork/articles/java/compress-1565076.html

FileInputStream fis = new FileInputStream("fig.zip"); ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));

Une fois qu'un flux d'entrée ZIP est ouvert, vous pouvez lire les entrées zip en utilisant la méthode getNextEntry qui renvoie un Objet ZipEntry. Si la fin du fichier est atteinte, getNextEntry renvoie null:

 -1
Author: Tech-IO, 2016-05-24 17:48:45