Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a stream is a zip file

Tags:

java

stream

zip

We have a requirement to determine whether an incoming InputStream is a reference to an zip file or zip data. We do not have reference to the underlying source of the stream. We aim to copy the contents of this stream into an OutputStream directed at an alternate location.

I tried reading the stream using ZipInputStream and extracting a ZipEntry. The ZipEntry is null if the stream is a regular file - as expected - however, in checking for a ZipEntry I loose the initial couple of bytes from the stream. Hence, by the time I know that the stream is a regular stream, I have already lost initial data from the stream.

Any thoughts around how to check if the InputStream is an archive without data loss would be helpful.

Thanks.

like image 744
AKS Avatar asked Nov 10 '10 20:11

AKS


People also ask

How do you tell if a file is a zip file?

You can identify compressed files by the file extension (. zip) and a zipper on the folder icon. Note: If the zipped folder is attached in an email, you must first save the zipped file to your computer before you can extract it.

Can a zip file be streamed?

Limitations. It's not possible to completely stream-write ZIP files. Small bits of metadata for each member file, such as its name, must be placed at the end of the ZIP. In order to do this, stream-zip buffers this metadata in memory until it can be output.

How can I tell if a ZIP file is empty?

Open it as a ZipFile and see, by iteration, whether it has any ZipEntry objects in it that have non-zero length. @user207421 Why non-zero length? If a zip file has an empty file, the zip file itself isn't empty.


2 Answers

Assuming your original inputstream is not buffered, I would try wrapping the original stream in a BufferedInputStream, before wrapping that in a ZipInputStream to check. You can use "mark" and "reset" in the BufferedInputStream to return to the initial position in the stream, after your check.

like image 70
Galactus Avatar answered Oct 25 '22 07:10

Galactus


This is how I did it.

Using mark/reset to restore the stream if the GZIPInputStream detects incorrect zip format (throws the ZipException).

/**
 * Wraps the input stream with GZIPInputStream if needed. 
 * @param inputStream
 * @return
 * @throws IOException
 */
private InputStream wrapIfZip(InputStream inputStream) throws IOException {
    if (!inputStream.markSupported()) {
        inputStream = new BufferedInputStream(inputStream);
    }
    inputStream.mark(1000);
    try {
        return new GZIPInputStream(inputStream);
    } catch (ZipException e) {
        inputStream.reset();
        return inputStream;
    }
}
like image 33
User0 Avatar answered Oct 25 '22 09:10

User0