开发者

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();
        }开发者_StackOverflow中文版
    }
    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.


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.


So you're not "downloading" via network? By download you mean to decompress files from a zip-archive to your local hard-disk?

You can easily decompress a zip file with these methods:

    private static File unZipFile(File zipFileIn) throws Exception {
        ZipFile unZipFile = new ZipFile(zipFileIn);
        Enumeration<? extends ZipEntry> entries = unZipFile.entries();
        String topFile = null;
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                // Assume directories are stored parents first then children
                String extractFile = entry.getName();
                if (topFile == null) {
                    topFile = extractFile;
                }
                // This is not robust, just a quick solution
                (new File(entry.getName())).mkdir();
                continue;
            }
            copyInputStream(unZipFile.getInputStream(entry),new BufferedOutp    utStream(new FileOutputStream(entry.getName())));
        }
        unZipFile.close();
        File newFile = new File(zipFileIn.getParentFile().getAbsoluteFile(),topFile);
        return newFile;
    }

    private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
            while((len = in.read(buffer)) >= 0)
            out.write(buffer, 0, len);
            in.close();
        out.close();
    }

The method returns you a File, which is the root of the decompressed files.

Perhaps it would be a good idea to ask your question more detailed on what you are trying to do. ATM everybody is guessing what you are trying to do instead of working on a solution.


I think that you need to read the contents on each entry and then call entry.closeEntry()


It sounds like you are trying to download the zip file whilst saving it simultaneously in binary and unzipped form. If that is the case, I would say download it first in binary form, then unzip it separately file disk afterwards.

If you don't want both, then you can choose which one you want to do, either by writing the plain stream to disk to get a binary zip file (no need to use a ZipInputStream); or by using a ZipInputStream and reading the data from each entry and writing it to disk (but don't use the plain input stream for writing to disk).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜