Finding a file in zipentry java
Asked Answered
I

3

5

I am trying to find a file within a zip file and get it as an InputStream. So this is what I am doing to get it so far and I am not certain if I am doing it correctly.

Here is a sample as the original is slightly longer but this is the main component...

public InputStream Search_Image(String file_located, ZipInputStream zip) 
    throws IOException {
    for (ZipEntry zip_e = zip.getNextEntry(); zip_e != null ; zip_e = zip.getNextEntry()) {
        if (file_located.equals(zip_e.getName())) {
            return zip;
        }
        if (zip_e.isDirectory()) {
            Search_Image(file_located, zip); 
        }
    }
    return null;
}

Now the main problem I am facing is that The ZipInputStream in Search_Image is the same as the original component of the ZipInputStream...

if(zip_e.isDirectory()) {
    //"zip" is the same as the original I need a change here to find folders again.
    Search_Image(file_located, zip); 
}

Now for the question, how do you get the ZipInputStream as the new zip_entry? Also please add in if I did anything wrong in my method as my logic with this class is still lacking.

Indices answered 20/6, 2012 at 16:1 Comment(0)
E
9

You should use the class ZipFile without worrying yourself with an input stream if you don't need it yet.

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

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

Some facts:

  • you should follow conventions for naming methods and variables in your code (Search_Image is not fine, searchImage is)
  • directories in zip files does not contain any file, they are just entries like everything else so you shouldn't try to recurse into them)
  • you should compare the name you provide by using endsWith(name) because the file could be inside a folder and a filename inside a zip always contains the path
Effy answered 20/6, 2012 at 16:13 Comment(2)
What happens when the image I seek is in a folder with the zip?. I had this as my original method problem was that this doesn't search the directories for the image.Indices
because you were using equals(..) instead that endsWith(..), take a look at my third point.Effy
T
6

Accessing to a zip entry using ZipInputStream is clearly not the way to do it as you will need to iterate over the entries to find it which is not a scalable approach because the performance will depend on total amount of entries in your zip file.

To get the best possible performances, you need to use a ZipFile in order to access directly to an entry thanks to the method getEntry(name) whatever the size of your archive.

public InputStream searchImage(String name, ZipFile zipFile) throws IOException {
    // Get the entry by its name
    ZipEntry entry = zipFile.getEntry(name);
    if (entry != null) {
        // The entry could be found
        return zipFile.getInputStream(entry);
    }
    // The entry could not be found
    return null;
}

Please note that the name to provide here is the relative path of your image in the archive using / as path separator so if you want to access to foo.png that is in the directory bar, the expected name will be bar/foo.png.

Thunderhead answered 12/10, 2016 at 18:18 Comment(0)
W
0

Here is my take on this:

ZipFile zipFile = new ZipFile(new File("/path/to/zip/file.zip"));
InputStream inputStream = searchWithinZipArchive("findMe.txt", zipFile);

public InputStream searchWithinZipArchive(String name, ZipFile file) throws Exception {
  Enumeration<? extends ZipEntry> entries = file.entries();
  while(entries.hasMoreElements()){
     ZipEntry zipEntry = entries.nextElement();
      if(zipEntry.getName().toLowerCase().endsWith(name)){
             return file.getInputStream(zipEntry);
      }
  }
  return null;
}
Witmer answered 24/5, 2017 at 4:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.