By dave | July 1, 2012

Java provides support for reading zip files in the form of ZipInputStream. This class provides an API where you can iterate over all the items in a given zip file, reading the data from the archive for each file.

In order to do this, first you must create the ZipInputStream instance giving the file that you wish to expand. Then you iterate using the getNextEntry method on the stream, which returns the header data for each entry in turn. Importantly this does not contain the data, which is actually read from the stream separately.

In order to execute the example below, you need to provide two parameters, firstly the zip file that is to be processed, and secondly the output directory where the uncompressed files are to be stored.

package com.thecoderscorner.example.compression;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * ZipReader reads the zip file specified using ZipInputStream,
 * it then outputs the raw files into the output directory
 * specified as a parameter.
 */
public class ZipReader
{
    private static final Logger LOGGER = Logger.getLogger("ZipReader");
    // Expands the zip file passed as argument 1, into the
    // directory provided in argument 2
    public static void main(String args[]) throws Exception
    {
        if(args.length != 2)
        {
            LOGGER.severe("zipreader zipfile outputdir");
            return;
        }

        // create a buffer to improve copy performance later.
        byte[] buffer = new byte[2048];

        Path outDir = Paths.get(args[1]);

        try(
                // we open the zip file using a java 7 try with resources block so
                // that we don't need a finally.
                ZipInputStream stream = new ZipInputStream(new FileInputStream(args[0]))
        )
        {
            LOGGER.info("Zip file: " + args[0] + " has been opened");

            // now iterate through each file in the zip archive. The get
            // next entry call will return a ZipEntry for each file in
            // the stream
            ZipEntry entry;
            while((entry = stream.getNextEntry())!=null)
            {
                // We can read the file information from the ZipEntry.
                String fileInfo = String.format("Entry: [%s] len %d added %TD",
                                entry.getName(), entry.getSize(),
                                new Date(entry.getTime()));
                LOGGER.info(fileInfo);

                Path filePath = outDir.resolve(entry.getName());

                // Now we can read the file data from the stream. We now
                // treat the stream like a usual input stream reading from
                // it until it returns 0 or less.
                try (
                        FileOutputStream  output = new FileOutputStream(filePath.toFile())
                )
                {
                    LOGGER.info("Writing file: " + filePath);
                    int len;
                    while ((len = stream.read(buffer)) > 0)
                    {
                        output.write(buffer, 0, len);
                    }
                }
            }
        }
    }
}

and to standard out

Mar 28, 2017 7:36:43 PM com.thecoderscorner.example.compression.ZipReader main
INFO: Zip file: c:/dev/temp/transistor.zip has been opened
Mar 28, 2017 7:36:43 PM com.thecoderscorner.example.compression.ZipReader main
INFO: Entry: [transistor.jpg] len 2329 added 05/02/15
Mar 28, 2017 7:36:43 PM com.thecoderscorner.example.compression.ZipReader main
INFO: Writing file: c:\dev\temp\zipout\transistor.jpg

Process finished with exit code 0

and in the output directory specified on the command line

dave@DAVESLAPTOP:/mnt/c/Dev/temp/zipout$ ls -l
total 4
-rwxrwxrwx 1 root root 2329 Mar 28 19:36 transistor.jpg

So what just happened?

We opened a zip file as a stream, and then we iterated over the files contained in the zip file. For each file entry found we output some of its characteristics and then saved the file to disk. Note that we read the file from the same stream object that we retrieved the ZipEntry.

Follow on to another article that combines this with Java 8 filtering. Filtered extraction from zip file using ZipInputStream and Java 8

Other pages within this category

comments powered by Disqus

This site uses cookies to analyse traffic, and to record consent. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Our privacy policy applies to all pages on our site

Should you need further guidance on how to proceed: External link for information about cookie management.

Send a message
X

Please use the forum for help with UI & libraries.

This message will be securely transmitted to our servers.