0

i have function for decompressing zips with multiple entries. Sometimes an exception is catched that states "Unexpected end of ZLIB Input stream". In my opinion it is not possible because i am using try with resrsources.

private boolean decompress(final Path blf) {

    final String pathToZip = blf.getParent().toString();

    final byte[] buffer = new byte[8192];

    try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(blf.toFile()))) {

        //We will unzip files in this folder
        if (!Files.exists(Paths.get(pathToZip))) {
            Files.createDirectory(Paths.get(pathToZip));
        }

        ZipEntry entry = zipInputStream.getNextEntry();
        final Path pathToFile = Paths.get(pathToZip + "\\" + entry.getName());

        //Faster procedure if the file already exists
        if (Files.exists((pathToFile))) {
            loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
                    "File already exists, skipping" + pathToFile));
            return true;
        }
        //Iterate over entries
        while (entry != null) {

            //If directory then create a new directory in uncompressed folder
            if (entry.isDirectory()) {
                loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
                        "Creating Directory:" + pathToFile));

                Files.createDirectories(pathToFile);
            } else {
                Files.createFile(pathToFile);
                loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
                        "File unzip: " + pathToFile.getFileName()));

                try (FileOutputStream fileOutputStream = new FileOutputStream(pathToFile.toString())) {
                    int len;

                    while ((len = zipInputStream.read(buffer)) > 0) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                }
                entry = zipInputStream.getNextEntry();
            }
        }
        return true;
    } catch (final IOException e) {
        loggerAnalysis.log(new LogRecord(Level.ERROR, "[Analysis]", e.getMessage()));
        return false;
    }
}

best regards

Sal.te
  • 115
  • 7
  • Why do you think that using try-with-resource prevents particular exceptions like “Unexpected end of ZLIB Input stream” to be thrown? In this specific case, the problem seems to be that you are not executing `entry = zipInputStream.getNextEntry();` after encountering a directory entry. But your code structure is horrible anyway. What’s the point of looping over all entries and trying to write them to the same `pathToFile`? Further, there will be a `NullPointerException` for empty zip files. If you wrote a simple loop without trying to do “clever” optimizations, you didn’t have these problems. – Holger Oct 17 '18 at 08:48
  • That exception is thrown when ZipEntryStream is not closing properly and i thought that try with resources would help. Not everty time i decompress i get this problem only 1 in 10 times or so. "entry = zipInputStream.getNextEntry();" thats the only save why to interate through a zipInputStream with mulitple entries? maybe there is the problem that i want to iterate but there is nothing... – Sal.te Oct 17 '18 at 09:37
  • Since ordinary zip files usually do not contain directory entries, it’s not surprising that this problem only materializes occasionally. Anyway, you have to call `getNextEntry()` *always* after processing an entry, I don’t think that this needs to be discussed. Further, it seems, you didn’t understand me. You are declaring `pathToFile` outside the loop and never changing it, you even declared it `final`. Then, you are using it as target for every zip entry. Think about. Clean up your code. – Holger Oct 17 '18 at 09:51

0 Answers0