从 ZipInputStream 复制条目 [英] Copying entries from ZipInputStream

查看:35
本文介绍了从 ZipInputStream 复制条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以像这样遍历 ZipInputStreamZipEntry s:

I am able to iterate over ZipEntrys of a ZipInputStream like this:

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?
}

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

How can I copy certain entries of this Zip file?

推荐答案

是的,这当然是可能的.当您调用 ZipInputStream.getNextEntry() 它将流定位在下一个数据条目的开始处,在这种情况下,您希望数据是子 zip 文件.流不会超过该数据的末尾,因此不必担心读入下一个条目,ZipInputStream 的条目基本上可以被视为它们自己的单个流.

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. 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.

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);
    }
}

这篇关于从 ZipInputStream 复制条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆