Sachin
Sachin

Reputation: 18747

java.util.zip.ZipException: invalid compression method

I am having some issues in dealing with zip files on Mac OS X 10.7.3.

I am receiving a zip file from a third party, which I have to process. My code is using ZipInputStream to do this. This code has been used several times before, without any issue but it fails for this particular zip file. The error which I get is as follows:

java.util.zip.ZipException: invalid compression method
    at java.util.zip.ZipInputStream.read(ZipInputStream.java:185)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:105)
    at org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.read(Unknown Source)
    at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
    at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)

I googled about it and I can see that there are some issues with ZipInputStream, e.g. this one.

I have also found some related questions on Stackoverflow, e.g. this one. But there is no proper, accepted/acceptable answer.

I have a couple questions:

  1. Has anyone found any concrete solution for this? Like any lates update or an all together different JAR which has same functionality but no issues
  2. On this link, the user phobuz1 mentions that "if non-standard compression method (method 6)" is used, then this problem occurs. Is there a way to find out which compression method is used? So that I can be sure of the reason of failure?

Note that as with some users, if I unzip the file on my local machine and re-zip it, it works perfectly fine.

EDIT 1:

The file which I am getting is in .zip format, I don't know which OS/utility program they are using to compress it. On my local machine I am using the built-in zip utility which comes with Mac OS X.

Upvotes: 4

Views: 11971

Answers (2)

Brandt Solovij
Brandt Solovij

Reputation: 2134

API JAVADOC : THIS is what actually compresses your file ( Updated Feb 2021 note, the oracle provided link expired, Duke University (no affiliation) however has the antiquated 1.4 javadoc available) : https://www2.cs.duke.edu/csed/java/jdk1.4.2/docs/api/java/util/zip/ZipEntry.html

per that interface, you are able to get and set compression methods ( getCompression() and setCompression(int), respectively).

good luck!

Upvotes: 1

Lion
Lion

Reputation: 19027

I'm using the following code in Java on my Windows XP OS to zip folders. It may at least be useful to you as a side note.

//add folder to the zip file
private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception
{
    File folder = new File(srcFolder);

    //check the empty folder
    if (folder.list().length == 0)
    {
        System.out.println(folder.getName());
        addFileToZip(path , srcFolder, zip,true);
    }
    else
    {
        //list the files in the folder
        for (String fileName : folder.list())
        {
            if (path.equals(""))
            {
                addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip,false);
            }
            else
            {
                addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip,false);
            }
        }
    }
}

//recursively add files to the zip files
private void addFileToZip(String path, String srcFile, ZipOutputStream zip,boolean flag)throws Exception
{
    //create the file object for inputs
    File folder = new File(srcFile);
    //if the folder is empty add empty folder to the Zip file
    if (flag==true)
    {
        zip.putNextEntry(new ZipEntry(path + "/" +folder.getName() + "/"));
    }
    else
    {
         //if the current name is directory, recursively traverse it to get the files
        if (folder.isDirectory())
        {
            addFolderToZip(path, srcFile, zip); //if folder is not empty
        }
        else
        {
            //write the file to the output
            byte[] buf = new byte[1024];
            int len;
            FileInputStream in = new FileInputStream(srcFile);
            zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));

            while ((len = in.read(buf)) > 0)
            {
                zip.write(buf, 0, len); //Write the Result
            }
        }
    }
}

//zip the folders
private void zipFolder(String srcFolder, String destZipFile) throws Exception
{
    //create the output stream to zip file result
    FileOutputStream fileWriter = new FileOutputStream(destZipFile);
    ZipOutputStream zip = new ZipOutputStream(fileWriter);
    //add the folder to the zip
    addFolderToZip("", srcFolder, zip);
    //close the zip objects
    zip.flush();
    zip.close();
}

private boolean zipFiles(String srcFolder, String destZipFile) throws Exception
{
    boolean result=false;
    System.out.println("Program Start zipping the given files");
    //send to the zip procedure
    zipFolder(srcFolder,destZipFile);
    result=true;
    System.out.println("Given files are successfully zipped");
    return result;
}

In this code, you need to invoke the preceding method zipFiles(String srcFolder, String destZipFile) by passing two parameters. The first parameter indicates your folder to be zipped and the second parameter destZipFile indicates your destination zip folder.


The following code is to unzip a zipped folder.

private void unzipFolder(String file) throws FileNotFoundException, IOException
{
    File zipFile=new File("YourZipFolder.zip");
    File extractDir=new File("YourDestinationFolder");

    extractDir.mkdirs();

    ZipInputStream inputStream = new ZipInputStream(new FileInputStream(zipFile));

    try
    {
        ZipEntry entry;
        while ((entry = inputStream.getNextEntry()) != null)
        {
            StringBuilder sb = new StringBuilder();
            sb.append("Extracting ");
            sb.append(entry.isDirectory() ? "directory " : "file ");
            sb.append(entry.getName());
            sb.append(" ...");
            System.out.println(sb.toString());

            File unzippedFile = new File(extractDir, entry.getName());
            if (!entry.isDirectory())
            {
                if (unzippedFile.getParentFile() != null)
                {
                    unzippedFile.getParentFile().mkdirs();
                }

                FileOutputStream outputStream = new FileOutputStream(unzippedFile);

                try
                {
                    byte[] buffer = new byte[1024];
                    int len;

                    while ((len = inputStream.read(buffer)) != -1)
                    {
                        outputStream.write(buffer, 0, len);
                    }
                }
                finally
                {
                    if (outputStream != null)
                    {
                        outputStream.close();
                    }
                }
            }
            else
            {
                unzippedFile.mkdirs();
            }
        }
    }
    finally
    {
        if (inputStream != null)
        {
            inputStream.close();
        }
    }
}

Upvotes: 1

Related Questions