I have a x.zip
file with the following structure (zip in zip in zip):
x.zip
/y.zip
/z.zip
I want to know the list of files and directories in the root of the z.zip
without any unpacking archives.
I have a x.zip
file with the following structure (zip in zip in zip):
x.zip
/y.zip
/z.zip
I want to know the list of files and directories in the root of the z.zip
without any unpacking archives.
You can read zip file contents directly from another zip entry’s InputStream. Be warned, however, that this is known to be rather slow:
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipException;
import java.util.stream.Stream;
public class NestedZipReader {
public List<String> listEntries(ZipFile zipFile,
List<String> nestedZipFiles)
throws IOException {
if (nestedZipFiles.isEmpty()) {
try (Stream<? extends ZipEntry> entries = zipFile.stream()) {
return entries.map(ZipEntry::getName).toList();
}
} else {
String name = nestedZipFiles.get(0);
ZipEntry entry = zipFile.getEntry(name);
if (entry != null) {
try (ZipInputStream nested = new ZipInputStream(
zipFile.getInputStream(entry))) {
return listEntries(nested, nestedZipFiles, 1);
}
}
throw new IllegalArgumentException("Entry not found: " + name);
}
}
public List<String> listEntries(ZipInputStream zipFile,
List<String> nestedZipFiles)
throws IOException {
return listEntries(zipFile, nestedZipFiles, 0);
}
private List<String> listEntries(ZipInputStream zipFile,
List<String> nestedZipFiles,
int nestedZipFileIndex)
throws IOException {
int count = nestedZipFiles.size();
if (nestedZipFileIndex >= count) {
List<String> names = new ArrayList<>();
ZipEntry entry;
while ((entry = zipFile.getNextEntry()) != null) {
names.add(entry.getName());
}
return names;
} else {
String name = nestedZipFiles.get(nestedZipFileIndex);
ZipEntry entry;
while ((entry = zipFile.getNextEntry()) != null) {
if (entry.getName().equals(name)) {
try (ZipInputStream nested = new ZipInputStream(zipFile)) {
return listEntries(
nested, nestedZipFiles, nestedZipFileIndex + 1);
}
}
}
throw new IllegalArgumentException("Entry not found: "
+ String.join(" => ",
nestedZipFiles.subList(0, nestedZipFileIndex + 1)));
}
}
public static void main(String[] args)
throws ZipException,
IOException {
NestedZipReader reader = new NestedZipReader();
List<String> entries;
try (ZipFile zipFile = new ZipFile(args[0])) {
entries = reader.listEntries(zipFile,
Arrays.asList(args).subList(1, args.length));
}
System.out.printf("%,d entries:%n%n", entries.size());
for (String entry : entries) {
System.out.println(entry);
}
}
}