从ZipInputStream复制条目

时间:2018-07-11 12:19:46

标签: java stream

我可以像这样迭代myapp的{​​{1}}中:

ZipEntry

如何复制此Zip文件的某些条目?

1 个答案:

答案 0 :(得分:0)

是的,当然有可能。调用ZipInputStream.getNextEntry()时,它将流定位在下一个数据条目的开头,在这种情况下,当您将数据作为子zip文件时,就需要该数据。该流不会超出该数据的末尾,因此不必担心读入下一个条目,实际上可以将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 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);
    }
}

在zip文件here上运行,它将打印出zip文件中的所有内容,包括子zip文件,并且不会丢失任何内容...