如何从 ZipEntry 创建输入流

Posted

技术标签:

【中文标题】如何从 ZipEntry 创建输入流【英文标题】:How do I create an input stream from a ZipEntry 【发布时间】:2009-11-12 15:27:30 【问题描述】:

我有一个包装 ZipEntrys 的类,但我正在努力了解如何编写一个从任何一个 ZipEntry 返回输入流的方法。我设法编写了一些可以返回 ZipFile 的输入流数组的东西,但我需要一种方法来从一个 ZipEntry 获取输入流。

【问题讨论】:

看:***.com/questions/3233555/… 【参考方案1】:

这个怎么样?

ZipFile zipFile = new ZipFile("file.zip");
ZipEntry zipEntry = zipFile.getEntry("fileName.txt");       
InputStream inputStream = zipFile.getInputStream(zipEntry);

【讨论】:

不幸的是,在 1.4.2_12 中创建 ZipFile 的新实例会泄漏文件句柄【参考方案2】:

您没有作为 ZipEntry 来源的 ZipFile 实例吗?如果你这样做,你可以使用 ZipFile.getInputStream(ZipEntry)。

https://docs.oracle.com/javase/8/docs/api/java/util/zip/ZipFile.html

PS。只是快速查看了代码,ZipEntry 不是 zip 文件中基础数据的包装器。据我所知,它只是条目的“占位符”(即压缩文件属性而不是数据)。实际流是通过 ZipFile 类中的 JNI 调用创建的。这意味着我不相信您可以以实际的方式做您想做的事情。

【讨论】:

马尔科姆,感谢您的帮助,我刚刚找到了那个方法。我现在的问题是,最初“打开”压缩文件的代码(当你执行 ZipFile zip = new ZipFile("path");),然后关闭它。如果我愿意,我可以阻止它关闭它,但我想知道 - 不关闭拉链/罐子会有什么后果?显然,如果我确实删除了 close() 命令,我将留下一个方法,以便用户稍后关闭它,但我想知道如果用户忘记了会发生什么 - 只是贪婪地占用内存?我知道它不是数据的包装器 - 我正在编写的是用于处理 Zip/Jar 文件的包装器。 保持打开状态对我来说不是一个好主意。同样,将关闭您的解决方案的责任推给用户也是如此。一个选项(可能 - 我猜你正在解决的问题)是包装 ZipEntry 并在包装类中包含 ZipFile 的句柄。这看起来有点重,但确实意味着您可以在需要时打开\关闭一个流到包装的 zip 条目。 如果我没有将它作为文件,但我总是可以重新创建 ZipInputStream(例如,从 Uri)怎么办?是否有可能让每个 ZipInputStream 的条目轻松地创建一个 InputStream?【参考方案3】:
 static void printInputStream(File zip) throws IOException
    
        ZipInputStream zin = new ZipInputStream(new FileInputStream(zip));
        for (ZipEntry zipEntry;(zipEntry = zin.getNextEntry()) != null; )
        
            System.out.println("reading zipEntry " + zipEntry.getName());
            Scanner sc = new Scanner(zin);
            while (sc.hasNextLine())
            
                System.out.println(sc.nextLine());
            
            System.out.println("reading " + zipEntry.getName() + " completed");
        
       zin.close();
    

在这里找到:getInputStream for a ZipEntry from ZipInputStream (without using the ZipFile class)

误解了从 zip 文件打开的输入流是什么。 解决方案:从 zip 文件打开输入流 ZipInputStreamzipInputStream = ZipInputStream(new FileInputStream(zipfile), 运行周期zipInputStream.getNextEntry()。 对于每一轮,您都有当前条目的输入流(之前为 zip 文件打开过); ..

【讨论】:

此方法比ZipFile.getInputStream() 方法更通用,因为它不需要来自实际文件的输入。因此,它可以用来读取内存中的 zip 文件内容。 别忘了关闭扫描仪 (sc)。

以上是关于如何从 ZipEntry 创建输入流的主要内容,如果未能解决你的问题,请参考以下文章

如何直接从输入流中插入值?

文件的输入流

IO流 读写文件

将固定字节从输入流存储到字节数组中

字节流和字符流

java中如何从一个文件中读文件,然后把另一个文件写入所读文件,最后再储存到另一个文件中