简体   繁体   English

从 ZipInputStream 复制条目

[英]Copying entries from ZipInputStream

I am able to iterate over ZipEntry s of a ZipInputStream like this:我可以像这样遍历ZipInputStream ZipEntry

ByteArrayInputStream schema = new ByteArrayInputStream(schemaData);
ZipInputStream zis = new ZipInputStream(schema);
ZipEntry entry;
while((entry = zis.getNextEntry()) != null) {
     String entryName = entry.getName();
     // filter based on entry name
     // how to copy this entry?
}

How can I copy certain entries of this Zip file?如何复制此 Zip 文件的某些条目?

Yes it is certainly possible.是的,这当然是可能的。 When you call ZipInputStream.getNextEntry() it positions the stream at the start of the next entry of data, in this case you want the data when it's a sub zip file.当您调用ZipInputStream.getNextEntry()它会将流定位在下一个数据条目的开头,在这种情况下,您希望数据是子 zip 文件。 The stream wont go past the end of that data so don't worry about reading into the next entry, the entries of a ZipInputStream can essentially be treated like an individual stream of their own.该流不会超过该数据的末尾,因此不必担心读入下一个条目, ZipInputStream的条目基本上可以被视为它们自己的单个流。

public static void main(String[] args) throws IOException {
    // ** specify an output directory to copy files to
    final File outDir = new File("path\\to\\...\\OutDir");

    // ** read the zip input stream and do for each entry...
    final String pathToZip = "path\\to\\...\\ZipTest.zip";
    try (InputStream is = new FileInputStream(pathToZip);
            ZipInputStream zis = new ZipInputStream(is);) {

        forEachZipEntry(zis, (zipEntry, subZipStream) -> {
            // ** specify how to consume each zip entry and stream...
            // ** apply filters here, based on the zip entry
            if (zipEntry.getName().equals("normalZippedDir.zip")) {
                // ** copy the zip stream to the file
                File outFile = new File(outDir, zipEntry.getName());
                try (FileOutputStream fis = new FileOutputStream(outFile);) {
                    // apache IOUtils or whatever copy method you want
                    IOUtils.copy(subZipStream, fis);
                } catch (IOException e) { e.printStackTrace(); }
            }
        });
    }
}

/**
 * Iterates through all {@linkplain ZipEntry}s of the given {@linkplain ZipInputStream} and
 * passes the current zip entry and stream to the provided {@linkplain BiConsumer}, but does
 * <b>not</b> recursively parse entries of nested zip files.
 */
public static void forEachZipEntry(ZipInputStream zis, BiConsumer<ZipEntry, ZipInputStream> consumer)
        throws IOException {
    Objects.requireNonNull(zis);
    Objects.requireNonNull(consumer);
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        consumer.accept(entry, zis);
    }
}

/**
 * Recursively iterates through <b>all</b> {@linkplain ZipEntry}s <i>(including entries of nested zip
 * files)</i> of the given {@linkplain ZipInputStream} passing the current zip entry and stream to
 * the provided {@linkplain BiConsumer}.
 */
public static void forEachZipEntryRecursive(ZipInputStream zis,
        BiConsumer<ZipEntry, ZipInputStream> consumer) throws IOException {
    Objects.requireNonNull(zis);
    Objects.requireNonNull(consumer);
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        consumer.accept(entry, zis);
        @SuppressWarnings("resource") // ** caller shall close `zis`
        ZipInputStream subZis = new ZipInputStream(zis);
        forEachZipEntryRecursive(subZis, consumer);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM