java - 为什么某些 zip 文件的文件内容未知

标签 java android zip compression skyepub

背景

我偶然发现了这个问题 here

分析

根据java docs对于 ZipEntry,有时请求压缩文件条目的大小只会返回 -1

但是,运行命令

$ unzip -l b17c024e-89f1-42f7-a546-91d46610cedb.epub 
Archive:  b17c024e-89f1-42f7-a546-91d46610cedb.epub
  Length     Date   Time    Name
 --------    ----   ----    ----
       20  01-27-12 11:17   mimetype
     2378  04-20-12 10:12   OEBPS/hayat-ghayr.html
     6436  02-06-12 11:06   OEBPS/content.opf
   112579  01-27-12 11:25   OEBPS/images/978-614-425-313-7-hayat-ghayr-cover.png
   182575  01-27-12 11:25   OEBPS/images/978-614-425-313-7-hayat_fmt.png
     7757  01-27-12 11:21   OEBPS/template.css
     5643  01-27-12 11:18   OEBPS/hayat-ghayr-2.html
    20144  01-27-12 11:17   OEBPS/hayat-ghayr-1.html
    65543  01-27-12 11:17   OEBPS/hayat-ghayr-3.html
    59434  01-27-12 11:17   OEBPS/hayat-ghayr-4.html
    66768  01-27-12 11:17   OEBPS/hayat-ghayr-5.html
    49117  01-27-12 11:17   OEBPS/hayat-ghayr-6.html
    65346  01-27-12 11:17   OEBPS/hayat-ghayr-7.html
    74196  01-27-12 11:17   OEBPS/hayat-ghayr-8.html
    73998  01-27-12 11:17   OEBPS/hayat-ghayr-9.html
    61031  01-27-12 11:17   OEBPS/hayat-ghayr-10.html
    68297  01-27-12 11:17   OEBPS/hayat-ghayr-11.html
    72084  01-27-12 11:17   OEBPS/hayat-ghayr-12.html
     2386  01-27-12 11:17   OEBPS/hayat-ghayr-13.html
    61132  01-27-12 11:17   OEBPS/hayat-ghayr-14.html
    46320  01-27-12 11:17   OEBPS/hayat-ghayr-15.html
    32673  01-27-12 11:17   OEBPS/hayat-ghayr-16.html
    88584  01-27-12 11:17   OEBPS/hayat-ghayr-17.html
    56474  01-27-12 11:17   OEBPS/hayat-ghayr-18.html
    52840  01-27-12 11:17   OEBPS/hayat-ghayr-19.html
    80022  01-27-12 11:17   OEBPS/hayat-ghayr-20.html
    50781  01-27-12 11:17   OEBPS/hayat-ghayr-21.html
     2765  01-27-12 11:17   OEBPS/hayat-ghayr-22.html
      265  01-27-12 11:17   META-INF/container.xml
    54942  01-27-12 11:17   OEBPS/images/277.png
     5549  01-27-12 11:17   OEBPS/toc.ncx
     1072  03-23-12 13:28   iTunesMetadata.plist
 --------                   -------
  1529151                   32 files

显示所有章节都有一个内容长度。 而且,如果我们解压缩同一个文件并使用更强的压缩再次重新压缩它。zipFile java 命令返回正确的内容大小

问题

这是 zip 库的错误还是原始压缩错误?我们怎么知道?

跟进问题

参见 How to access a zipEntry from a streamed zip file in memory

最佳答案

ZIP 将元数据存储在存档中的几个不同位置(“本地文件头”、“中央目录”,有时还有“数据描述符”)。只有“本地文件头”在文件内容的前面——“中心目录”在存档的最后。只有“中心目录”才是真实的,在“本地文件头”中不指定任何大小是完全有效的。

请参阅 https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT 中的第 4.4.8/4.4.9 节讨论大小字段

If bit 3 of the general purpose bit flag is set, these fields are set to zero in the local header and the correct values are put in the data descriptor and in the central directory.

“数据描述符”紧跟在条目的压缩内容之后 - 因此在从不可搜索的流读取时在读取条目的实际内容之前不可用。

当使用 ZipArchiveInputStream 时,您会在读取“本地文件头”后立即获得 ZipEntry(因为底层流可能不可搜索),因此大小信息可能会丢失。 ZipFile 在幕后使用 RandomAccessFile 并且可以读取“中央目录” - unzip 和 friend 也是如此 - 所以他们知道的比 ZipArchiveInputStream.

关于java - 为什么某些 zip 文件的文件内容未知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36788065/

相关文章:

android - 来自服务的持久性 android 通知

c++ - 用于解压缩受密码保护的文件的库

zip - 重新压缩 MDzip 文件

Java:访问类内的 transient 对象字段

java - 如何在组件的某些特定区域捕获鼠标移动事件?

java - ;在条件结束时导致意外行为

android - Android 环境中的 "scrim"是什么?

android - Fragment$Companion 无法在 BottomNavigationView 监听器上转换为 androidx.fragment.app.Fragment

linux - 使用 shell 命令比较 ZIP 文件和目录

java - 如何使用 Android Java 录制直播?