How can I convert ZipInputStream to InputStream?
Asked Answered
C

6

4

I have code, where ZipInputSream is converted to byte[], but I don't know how I can convert that to inputstream.

private void convertStream(String encoding, ZipInputStream in) throws IOException,
        UnsupportedEncodingException
{
    final int BUFFER = 1;
    @SuppressWarnings("unused")
    int count = 0;
    byte data[] = new byte[BUFFER];
    while ((count = in.read(data, 0, BUFFER)) != -1) 
    {
       // How can I convert data to InputStream  here ?                    
    }
}
Clothilde answered 21/10, 2011 at 18:54 Comment(2)
What exactly are you trying to do? Unzip a single entry in the stream?Ophir
Yes, I want single file from stream as InputStream if it is possible.Clothilde
C
3

Here is how I solved this problem. Now I can get single files from ZipInputStream to memory as InputStream.

private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding) throws IOException
{
    final int BUFFER = 2048;
    int count = 0;
    byte data[] = new byte[BUFFER];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    while ((count = in.read(data, 0, BUFFER)) != -1) {
        out.write(data);
    }       
    InputStream is = new ByteArrayInputStream(out.toByteArray());
    return is;
}
Clothilde answered 22/10, 2011 at 10:6 Comment(6)
can you pls specify where ZipEntry entry, String encoding are used and why?Folium
You should avoid to to that, it will cause OutOfMemoryError on large files. Instead you can just use the ZipInputStream. See #20021482Sweptwing
What are the second and third arguments for? They aren't used at all.Allanadale
while ((count = in.read(buffer)) > 0) {out.write(BUFFER, 0, count);}Hofstetter
you don't need any of this, as noted by ExtremeCoder ZipInputStream IS a InputStream, or if you prefer "private InputStream convertZipInputStreamToInputStream(ZipInputStream in) { return in; }"Aurthur
This particular answer will add extra data in the out stream with out.write(data) . Correct way should be out.write(data, 0, count) Wasted a lot of time finding issue in my code when the problem was this. Please see this answer for reference: https://mcmap.net/q/1174757/-bytearrayoutputstream-tostring-generating-extra-characters.Outflow
G
10

ZipInputStream is a subclass of InputStream.

http://download.oracle.com/javase/6/docs/api/java/util/zip/ZipInputStream.html

Guimar answered 21/10, 2011 at 18:55 Comment(0)
C
3

Here is how I solved this problem. Now I can get single files from ZipInputStream to memory as InputStream.

private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding) throws IOException
{
    final int BUFFER = 2048;
    int count = 0;
    byte data[] = new byte[BUFFER];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    while ((count = in.read(data, 0, BUFFER)) != -1) {
        out.write(data);
    }       
    InputStream is = new ByteArrayInputStream(out.toByteArray());
    return is;
}
Clothilde answered 22/10, 2011 at 10:6 Comment(6)
can you pls specify where ZipEntry entry, String encoding are used and why?Folium
You should avoid to to that, it will cause OutOfMemoryError on large files. Instead you can just use the ZipInputStream. See #20021482Sweptwing
What are the second and third arguments for? They aren't used at all.Allanadale
while ((count = in.read(buffer)) > 0) {out.write(BUFFER, 0, count);}Hofstetter
you don't need any of this, as noted by ExtremeCoder ZipInputStream IS a InputStream, or if you prefer "private InputStream convertZipInputStreamToInputStream(ZipInputStream in) { return in; }"Aurthur
This particular answer will add extra data in the out stream with out.write(data) . Correct way should be out.write(data, 0, count) Wasted a lot of time finding issue in my code when the problem was this. Please see this answer for reference: https://mcmap.net/q/1174757/-bytearrayoutputstream-tostring-generating-extra-characters.Outflow
P
0

Please find below example of function that will extract all files from ZIP archive. This function will not work with files in subfolders:

private static void testZip() {
    ZipInputStream zipStream = null;
    byte buff[] = new byte[16384];
    int readBytes;
    try {
        FileInputStream fis = new FileInputStream("./test.zip");
        zipStream = new ZipInputStream(fis);
        ZipEntry ze;
        while((ze = zipStream.getNextEntry()) != null) {
            if(ze.isDirectory()) {
                System.out.println("Folder : "+ze.getName());
                continue;//no need to extract
            }
            System.out.println("Extracting file "+ze.getName());
            //at this moment zipStream pointing to the beginning of current ZipEntry, e.g. archived file
            //saving file
            FileOutputStream outFile = new FileOutputStream(ze.getName());
            while((readBytes = zipStream.read(buff)) != -1) {
                outFile.write(buff, 0, readBytes);
            }
            outFile.close();                
        }

    } catch (Exception e) {
        System.err.println("Error processing zip file : "+e.getMessage());
    } finally {
        if(zipStream != null)
            try {
                zipStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}
Purdy answered 27/1, 2017 at 17:20 Comment(1)
Not what was asked for.Allanadale
S
0

Below works for me for FileOutputStream:

try (ZipInputStream zin = new ZipInputStream(response.getInputStream())) {
        for (ZipEntry zipEntry = zin.getNextEntry(); zipEntry != null; zipEntry = zin.getNextEntry()) {
            File f = new File(dir, zipEntry.getName());
            try (FileOutputStream fout = new FileOutputStream(f)) {
                 int len;
                 byte[] buffer = new byte[1024];
                 while ((len = zin.read(buffer)) > 0) {
                     fout.write(buffer, 0, len);
                 }
                zin.closeEntry();
            }
        }
    }
Strychninism answered 30/6, 2022 at 4:59 Comment(0)
F
-1

ZipInputStream allows to read ZIP contents directly: iterate using getNextEntry() until you find the entry you want to read and then just read from the ZipInputStream.

If you don't want to just read ZIP content, but you need to apply an additional transform to the stream before passing to the next step, you can use PipedInputStream and PipedOutputStream. The idea would be similar to this (written from memory, might not even compile):

import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public abstract class FilterThread extends Thread {
    private InputStream unfiltered;
    public void setUnfilteredStream(InputStream unfiltered) {
        this.unfiltered = unfiltered;
    }
    private OutputStream threadOutput;
    public void setThreadOutputStream(OutputStream threadOutput) {
        this.threadOutput = threadOutput;
    }    

    // read from unfiltered stream, filter and write to thread output stream
    public abstract void run();
}

...

public InputStream getFilteredStream(InputStream unfiltered, FilterThread filter) {
    PipedInputStream filteredInputStream = new PipedInputStream();
    PipedOutputStream threadOutputStream = new PipedOutputStream(filteredInputStream);

    filter.setUnfilteredStream(unfiltered);
    filter.setThreadOuptut(threadOutputStream);
    filter.start();

    return filteredInputStream;
}

...

public void clientCode() {
    ...
    ZipInputStream zis = ...;// get ZIP stream
    FilterThread filter = ...; // assign your implementation of FilterThread that transforms your ZipInputStream

    InputStream filteredZipInputStream = getFilteredStream(zis, filter);
    ...
}
Freeforall answered 21/10, 2011 at 19:41 Comment(0)
L
-2

The zip code is fairly easy but I had issues with returning ZipInputStream as Inputstream. For some reason, some of the files contained within the zip had characters being dropped. The below was my solution and so far its been working.

private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ,
        String operation) throws ServiceFault
{
    Map<String, InputStream> fileEntries = new HashMap<String, InputStream>();
    try
    {

        DataSource dsZ = dhZ.getDataSource();

        ZipInputStream zipIsZ = new ZipInputStream(dhZ.getDataSource()
                .getInputStream());

        try
        {
            ZipEntry entry;
            while ((entry = zipIsZ.getNextEntry()) != null)
            {
                if (!entry.isDirectory())
                {
                    Path p = Paths.get(entry.toString());
                    fileEntries.put(p.getFileName().toString(),
                            convertZipInputStreamToInputStream(zipIsZ));
                }

            }
        }
        finally
        {
            zipIsZ.close();
        }

    }
    catch (final Exception e)
    {
        faultLocal(LOGGER, e, operation);
    }

    return fileEntries;
}
private InputStream convertZipInputStreamToInputStream(
        final ZipInputStream in) throws IOException
{
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    IOUtils.copy(in, out);
    InputStream is = new ByteArrayInputStream(out.toByteArray());
    return is;
}
Longwood answered 17/11, 2016 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.