Search code examples
javainputstreamzipinputstream

Problem opening/downloading zip-file after decompression (Java/ZipInputStream)


The background
Currently, I try to get a zip-file through a HTTP-servlet with a HTTP-request. The received zip-file contains three different files. These files contain information I want to filter out and doing this from the source is not an option (that's just how it is, though I am aware it would be much better).

Because I cant filter out some information in the file from the source, where the file is build from the beginning, my solution is to decompress the file, read these three files as strings and then filter them. In the end "rebuild" all as a "zipfile" (inputStream) and return the inputStream.

The problem
Currently, I've made a class to handle the decompression and filtering of the file. In the end I just want to return the new inputStream containing the zip-file and the three files inside.

I've come as far as get the content from the HTTP entity into a inputStream, decompress this inputStream and get the three files as three strings. To just try to see if this work, I currently don't want to do more than just decompress them and just close the inputStream and return it.. This does however cause an exception when I return the inputStream:

 java.io.IOException: Attempted read on closed stream.

This is because the inputStream is used outside the function I present below. As I close the zipInputStream, I probably also closes the inputStream for further work.

The current code

public InputStream convertInputStream(HttpEntity entity)
{
    InputStream inputStream = null;
    try
    {
        inputStream = entity.getContent();
    }
    catch (IOException e11)
    {

    }

    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    Vector <String>entryVector = new Vector<String>();
    ZipEntry entry;
    try
    {
        String entryValue;
        while((entry = zipInputStream.getNextEntry()) != null)
        {           
            System.out.println("Unzipping file: " + entry.getName() + "...");
            byte [] buf = new byte[(int) entry.getSize()];
            zipInputStream.read(buf);
            entryValue = new String(buf);
            entryVector.add(entryValue);
            zipInputStream.closeEntry();
        }
    }
    catch(IOException e)
    {
        System.out.println("error in getting next entry.");
    }
    finally
    {
        try 
        {
            zipInputStream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        System.out.println("Unzipping done!");
    }
    return inputStream;
}

I hope I manage to express this as clear as possible. I can still see that this is very confusing to understand when I can't show the whole solution outside this function.


Solution

  • Where you print "unzipping file", you are not actually unzipping anything. If you want to do that, you need to read the content of the entry from the ZipInputStream using the read() function and write that to a file.

    EDIT: You can try reading the (compressed) zip file from the input stream into a byte array. Then create a ByteArrayInputStream on that array and then wrap your ZipInputStream around that. Then you can safely close the input stream without closing the underlying stream.

    Also, make sure that the file's content as String is actually useful. new String(byte[]) creates a string using the default encoding, so this may very well be useless.