问题
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