Baishampayan Ghose Baishampayan Ghose - 4 months ago 16
Java Question

Unzipping a file from InputStream and returning another InputStream

I am trying to write a function which will accept an

InputStream
with zipped file data and would return another
InputStream
with unzipped data.

The zipped file will only contain a single file and thus there is no requirement of creating directories, etc...

I tried looking at
ZipInputStream
and others but I am confused by so many different types of streams in Java.

Answer

Concepts

GZipinputstream is for streams (or files) ziped as gzip (".gz" extension). It doesn't have any header information.

GZipInputStream is for [zippeddata]

If you have a real zip file, you have to user ZipFile to open the file, ask for the list of files (one in your example) and ask for the decompressed input stream.

ZipFile is for a file with [header information + zippeddata]

Your method, if you have the file, would be something like:

// ITS PSEUDOCODE!!

private InputStream extractOnlyFile(String path) {
   ZipFile zf = new ZipFile(path);
   Enumeration e = zf.entries();
   ZipEntry entry = (ZipEntry) e.nextElement(); // your only file
   return zf.getInputStream(entry);
}

Reading an InputStream with the content of a .zip file

Ok, if you have an InputStream you can use (as @cletus says) ZipInputStream. It reads a stream including header data.

ZipInputStream is for a stream with [header information + zippeddata]

Important: if you have the file in your PC you can use ZipFile class to access it randomly

This is a sample of reading a zip-file through an InputStream:

import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


public class Main {
    public static void main(String[] args) throws Exception
    {
        FileInputStream fis = new FileInputStream("c:/inas400.zip");

        // this is where you start, with an InputStream containing the bytes from the zip file
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry entry;
            // while there are entries I process them
        while ((entry = zis.getNextEntry()) != null)
        {
            System.out.println("entry: " + entry.getName() + ", " + entry.getSize());
                    // consume all the data from this entry
            while (zis.available() > 0)
                zis.read();
                    // I could close the entry, but getNextEntry does it automatically
                    // zis.closeEntry()
        }
    }
}