从ZipInputStream中获取ZipEntry的InputStream是否可行?

31

我从另一个来源接收到了一个ZipInputStream,我需要将第一个条目的InputStream提供给另一个来源。

我希望能够在不将临时文件保存在设备上的情况下完成此操作,但是我所知道的获取单个条目的InputStream的唯一方法是通过ZipFile.getInputStream(entry),而我有的是ZipInputStream而不是ZipFile,因此这是不可能的。

所以我最好的解决方案是:

  1. 将传入的InputStream保存到文件中
  2. 作为ZipFile读取文件
  3. 使用第一个条目的InputStream
  4. 删除临时文件。
3个回答

38

了解:

完全有可能,调用ZipInputStream.getNextEntry()InputStream定位到条目的开头,因此提供ZipInputStream等同于提供ZipEntryInputStream

ZipInputStream足够智能,可以处理条目的EOF(文件结束标识)。

p.


3
我不明白你的意思是什么?你能添加一段代码示例吗? - Whitecat
4
他的意思是ZipInputStream既可以用于整个zip文件,也可以用于读取每个组件。getNextEntry()函数会继续到第一个组件,读取它,再执行另一个getNextEntry()函数,这样你的流就重置为第二个组件以此类推。实际上很聪明。 - akauppi

18

除了@pstanton的帖子,这里还有一个代码示例。我使用以下代码解决了这个问题。在没有示例的情况下,很难理解先前的答案。

//If you just want the first file in the zipped InputStream use this code. 
//Otherwise loop through the InputStream using getNextEntry()
//till you find the file you want.
private InputStream convertToInputStream(InputStream stream) throws IOException {
    ZipInputStream zis = new ZipInputStream(stream);
    zis.getNextEntry();
    return zis;
} 

使用此代码,您可以返回已压缩文件的InputStream。


在读取了第一个组件之后,可以再次使用'.getNextEntry()'来读取第二个组件。 - akauppi
你需要关闭zis,然后选择下一个。zis.closeEntry(); zis.getNextEntry(); - Sergey Nemchinov

1
邮政编码很容易,但我在将ZipInputStream返回为InputStream时遇到了问题。由于某种原因,压缩包中包含的一些文件出现了字符丢失的情况。下面是我的解决方案,目前它已经可以正常工作。
private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ,
        String operation) throws ServiceFault {
    Map<String, InputStream> fileEntries = new HashMap<String, InputStream>();
    try {
        ZipInputStream zipIsZ = new ZipInputStream(dhZ.getDataSource()
        .getInputStream());

        try {
            ZipEntry entry;
            while ((entry = zipIsZ.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    Path p = Paths.get(entry.toString());
                    fileEntries.put(p.getFileName().toString(),
                    convertZipInputStreamToInputStream(zipIsZ));
                }
            }
        }
        finally {
            zipIsZ.close();
        }

    } catch (final Exception e) {
        faultLocal(LOGGER, e, operation);
    }

    return fileEntries;
}
private InputStream convertZipInputStreamToInputStream(
final ZipInputStream in) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    IOUtils.copy(in, out);
    InputStream is = new ByteArrayInputStream(out.toByteArray());
    return is;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接