Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting specific file from ZipInputStream

I can go through ZipInputStream, but before starting the iteration I want to get a specific file that I need during the iteration. How can I do that?

ZipInputStream zin = new ZipInputStream(myInputStream)
while ((entry = zin.getNextEntry()) != null)
 {
    println entry.getName()
}
like image 230
Jils Avatar asked Apr 08 '15 12:04

Jils


People also ask

How do I read a ZipInputStream file?

ZipInputStream. read(byte[] buf, int off, int len) method reads from the current ZIP entry into an array of bytes. If len is not zero, the method blocks until some input is available; otherwise, no bytes are read and 0 is returned.

How do I get files from ZipEntry?

To read the file represented by a ZipEntry you can obtain an InputStream from the ZipFile like this: ZipEntry zipEntry = zipFile. getEntry("dir/subdir/file1.

How do I get InputStream from ZipEntry?

Solution: open input stream from zip file ZipInputStream zipInputStream = ZipInputStream(new FileInputStream(zipfile) , run cycle zipInputStream. getNextEntry() . For every round you have the inputstream for current entry (opened for zip file before); .. This method is more generic than ZipFile.

How can I read the content of a ZIP file without unzipping it in Java?

Methods. getComment(): String – returns the zip file comment, or null if none. getEntry(String name): ZipEntry – returns the zip file entry for the specified name, or null if not found. getInputStream(ZipEntry entry) : InputStream – Returns an input stream for reading the contents of the specified zip file entry.

What is the use of zipinputstream in Java?

Doing this reduces memory space occupied and makes transport of files bundle easy. ZipInputStream which are used to read the file entries in zip files present in the zip. In Java, there are two classes namely ZipFile and ZipInputStream which are used to read the file entries present in zip files.

How do I get next entry in ZIP input stream?

A ZipInputStream is created from the buffered FileInputStream . The try-with-resources closes the streams when they are not needed anymore. In a while loop, we go through the entries of the ZIP file with getNextEntry () method. It returns null if there are no more entries.

How to read file entries in ZIP file in Java?

ZipInputStream which are used to read the file entries in zip files present in the zip. In Java, there are two classes namely ZipFile and ZipInputStream which are used to read the file entries present in zip files.

How to read the contents of a zip file in Python?

Return value : The function returns a InputStream Object to read the contents of the ZipFile Entry. Example 1: We will create a file named zip_file and get the zip file entry using getEntry () function and then get the Input Stream object to read the contents of the file.”file.zip” is a zip file present in f: directory.


4 Answers

use the getName() method on ZipEntry to get the file you want.

ZipInputStream zin = new ZipInputStream(myInputStream)
String myFile = "foo.txt";
while ((entry = zin.getNextEntry()) != null)
{
    if (entry.getName().equals(myFileName)) {
        // process your file
        // stop looking for your file - you've already found it
        break;
    }
}

From Java 7 onwards, you are better off using ZipFile instead of ZipStream if you only want one file and you have a file to read from:

ZipFile zfile = new ZipFile(aFile);
String myFile = "foo.txt";
ZipEntry entry = zfile.getEntry(myFile);
if (entry) {
     // process your file           
}
like image 159
Robert Christie Avatar answered Oct 07 '22 12:10

Robert Christie


If the myInputStream you're working with comes from a real file on disk then you can simply use java.util.zip.ZipFile instead, which is backed by a RandomAccessFile and provides direct access to the zip entries by name. But if all you have is an InputStream (e.g. if you're processing the stream directly on receipt from a network socket or similar) then you'll have to do your own buffering.

You could copy the stream to a temporary file, then open that file using ZipFile, or if you know the maximum size of the data in advance (e.g. for an HTTP request that declares its Content-Length up front) you could use a BufferedInputStream to buffer it in memory until you've found the required entry.

BufferedInputStream bufIn = new BufferedInputStream(myInputStream);
bufIn.mark(contentLength);
ZipInputStream zipIn = new ZipInputStream(bufIn);
boolean foundSpecial = false;
while ((entry = zin.getNextEntry()) != null) {
  if("special.txt".equals(entry.getName())) {
    // do whatever you need with the special entry
    foundSpecial = true;
    break;
  }
}

if(foundSpecial) {
  // rewind
  bufIn.reset();
  zipIn = new ZipInputStream(bufIn);
  // ....
}

(I haven't tested this code myself, you may find it's necessary to use something like the commons-io CloseShieldInputStream in between the bufIn and the first zipIn, to allow the first zip stream to close without closing the underlying bufIn before you've rewound it).

like image 27
Ian Roberts Avatar answered Oct 07 '22 14:10

Ian Roberts


Look at Finding a file in zip entry

ZipFile file = new ZipFile("file.zip");
ZipInputStream zis = searchImage("foo.png", file);

public searchImage(String name, ZipFile file)
{
  for (ZipEntry e : file.entries){
    if (e.getName().endsWith(name)){
      return file.getInputStream(e);
    }
  }

  return null;
}
like image 45
RSCh Avatar answered Oct 07 '22 13:10

RSCh


I'm late to the party, but all above "answers" does not answer the question and accepted "answer" suggest create temp file which is inefficient.

Lets create sample zip file:

seq 10000 | sed "s/^.*$/a/"> /tmp/a
seq 10000 20000 | sed "s/^.*$/b/"> /tmp/b
seq 20000 30000 | sed "s/^.*$/c/"> /tmp/c
zip /tmp/out.zip /tmp/a /tmp/b /tmp/c

so now we have /tmp/out.zip file, which contains 3 files, each of them full of chars a, b or c.

Now lets read it:

  public static void main(String[] args) throws IOException {
        ZipInputStream zipStream = new ZipInputStream(new FileInputStream("/tmp/out.zip"));
            ZipEntry zipEntry;
            while ((zipEntry = zipStream.getNextEntry()) != null) {
                String name = zipEntry.getName();
                System.out.println("Entry: "+name);
                if (name.equals("tmp/c")) {
                    byte[] bytes = zipStream.readAllBytes();
                    String s = new String(bytes);
                    System.out.println(s);
                }
            }
    }

method readAllBytes seems weird, while we're in processing of stream, but it seems to work, I tested it also on some images, where there is higher chance of failure. So it's probably just unintuitive api, but it seems to work.

like image 1
Martin Mucha Avatar answered Oct 07 '22 14:10

Martin Mucha