Reputation: 105
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.
Upvotes: 5
Views: 16380
Reputation: 1228
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;
}
Upvotes: 0
Reputation: 133567
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:
Search_Image
is not fine, searchImage
is)endsWith(name)
because the file could be inside a folder and a filename inside a zip always contains the pathUpvotes: 9
Reputation: 44965
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
.
Upvotes: 6