背景
我偶然发现了这个问题 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/