I have an ZipInputStream made from a byte array , I can iterate through the zipInputStream ZipEntrys but I cant find a method to get the data from the ZipEntry (ZipENtry.getExtras() is null on every entry) how would i go to extract all the files one by one each one to a specific location on my disk ?
try {
ZipInputStream zipInputStream = new ZipInputStream(zip.getBody().getInputStream());
ZipEntry temp;
while((temp = zipInputStream.getNextEntry()) != null){
File outputFile = new File(temp.getName());
try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
System.out.println(temp.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
}
CodePudding user response:
Inside the while loop you just need one line call to transfer the current entry to target file:
Files.copy(zipInputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
This will copy the current entry contents but won't close zipInputStream
, then your loop may continue to the next entry.
CodePudding user response:
The answer is: The ZipInputStream
itself. It's an InputStream
. You can call read()
on it.
ZipInputStream is a bit of weird fellow. It has additional methods on top of the usual (.read()
, mostly), such as getNextEntry()
.
getNextEntry()
doesn't just get you a ZipEntry object - it also forwards the inputstream itself 'past' the file you were on so that it is now at the start of the new file. This also means ZipInputStreams bounce between states. You can have a ZIS that is currently at end of file (i.e. read()
would return -1
), then you call .getNextEntry()
and poof you can read from it again.
You end up with something like:
while ((temp = zipInputStream.getNextEntry()) != null) {
File outputFile = new File(temp.getName());
try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
System.out.println(temp.getName());
zipInputStream.transferTo(outputStream);
}
transferTo
is a default method that does what you usually want to do: Allocate a buffer, then read from the buffer, then write as many bytes as were read to the target, and keep doing that over and over until the read calls return -1
(indicating we're at the end).