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

时间:2016-04-22 07:54:01

标签: java android zip compression skyepub

背景

我偶然发现了这个问题here

分析

根据ZipEntry的java docs,有时请求zipfile条目的大小只返回-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

1 个答案:

答案 0 :(得分:2)

ZIP将档案内的元数据存储在几个不同的地方("本地文件头","中心目录"有时候"数据描述符")。只有"本地文件头"在文件的内容前面 - "中心目录"在归档的最后。只有"中心目录"掌握了全部真相,在"本地文件头中没有指定任何大小是完全有效的。

参见https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT中关于大小字段

的第4.4.8 / 4.4.9节
  

如果设置了通用位标志的第3位,          这些字段在本地标题中设置为零          正确的值放在数据描述符和          在中央目录。

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

使用ZipArchiveInputStream时,只要"本地文件标题"就会获得ZipEntry。已被读取(因为底层流可能不可搜索),因此可能缺少大小信息。 ZipFile使用RandomAccessFile封面,可以阅读"中心目录" - unzip和朋友一样 - 所以他们知道的不仅仅是ZipArchiveInputStream