gpt4 book ai didi

java - 安卓 ZipInputStream : only DEFLATED entries can have EXT descriptor

转载 作者:行者123 更新时间:2023-11-29 04:24:17 24 4
gpt4 key购买 nike

在我的 android 设备上,我需要提取一个文件(一个 xapk,据我所知这是一个普通的 zip 存档),我从内容 uri 中获得。我正在使用这行代码创建 ZipInputStream:

ZipInputStream zis = new ZipInputStream(getContentResolver().openInputStream(zipUri));

然后我尝试读取存档的第一个条目:

ZipEntry entry = zis.getNextEntry()

问题是我得到了这个异常:

java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor

我 100% 确定存档中没有 0bytes 文件,并且我可以使用设备中的其他实用程序(RAR、解压缩等)提取相同的存档。

如果我使用带有硬编码路径的 ZipFile(因此不涉及内容 uri),我可以毫无问题地提取相同的存档,因此问题与带有 uri 的 ZipInputStream 有关。另一方面,我不能在这里使用 ZipFile,因为它不支持内容 uris。

最佳答案

不幸的是,目前唯一的答案是:

不要像 ZipInputStream 那样以流模式处理 ZIP 文件。似乎所有当前可用的 ZIP 处理组件,如来自 JRE 的 ZipInputStream 和来自 Apache commons-compressZipArchiveInputStream无法处理此类 ZIP 文件。

apache commons-compress 帮助页面上对问题的描述非常好:

ZIP archives know a feature called the data descriptor which is a wayto store an entry's length after the entry's data. This can only workreliably if the size information can be taken from the centraldirectory or the data itself can signal it is complete, which is truefor data that is compressed using the DEFLATED compression algorithm.

ZipFile has access to the central directory and can extract entriesusing the data descriptor reliably. The same is true forZipArchiveInputStream as long as the entry is DEFLATED. For STOREDentries ZipArchiveInputStream can try to read ahead until it finds thenext entry, but this approach is not safe and has to be enabled by aconstructor argument explicitly.

https://commons.apache.org/proper/commons-compress/zip.html

解决方案

避免此问题的唯一可能是使用 ZipFile,但是 ZipFile JRE 的实现需要真实文件,因此您可能必须将数据保存到临时文件。

或者如果您改用 ZipFile来自 Apache commons-compress 并且您已经将 ZIP 文件完全保存在内存中,您可以避免使用 SeekableInMemoryByteChannel 将其保存到临时文件。


编辑:使用 Apache (Kotlin) 的内存 ZipFile 的解决方案:

ByteArrayOutputStream().use { byteArrayOutputStream ->
inputStream.copyTo(byteArrayOutputStream)
ZipFile(SeekableInMemoryByteChannel(byteArrayOutputStream.toByteArray())).use {
for (entry in it.entries) {
it.getInputStream(entry).copyTo(someOutputStream)
}
}
}

关于java - 安卓 ZipInputStream : only DEFLATED entries can have EXT descriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47208272/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com