JavaEar 专注于收集分享传播有价值的技术资料

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.

2个回答

    最佳答案
  1. 参考答案2
  2. 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();
            }
        }
    }