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()
}
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.
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.
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.
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.
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.
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.
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.
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.
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
}
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).
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With