Finding a file in zipentry java

可紊 提交于 2019-12-10 17:13:00

问题


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.


回答1:


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



回答2:


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.




回答3:


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;
}


来源:https://stackoverflow.com/questions/11123528/finding-a-file-in-zipentry-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!