测试文件是否为 zip 文件的好方法是什么?

问题描述 投票:0回答:10

我正在寻找新的文件格式规范,该规范表示该文件可以是基于 xml 的文件,也可以是包含 xml 文件和其他文件的 zip 文件。

两种情况下的文件扩展名相同。 我可以通过哪些方式测试文件来决定是否需要解压或只是读取?

c++ file-io compression unzip
10个回答
32
投票

zip 文件格式由 PKWARE 定义。您可以在此处找到他们的文件规范。

在顶部附近,您会发现标题规范:

A. 本地文件头:

    local file header signature     4 bytes  (0x04034b50)
    version needed to extract       2 bytes
    general purpose bit flag        2 bytes
    compression method              2 bytes
    last mod file time              2 bytes
    last mod file date              2 bytes
    crc-32                          4 bytes
    compressed size                 4 bytes
    uncompressed size               4 bytes
    file name length                2 bytes
    extra field length              2 bytes

    file name (variable size)
    extra field (variable size)

从中您可以看到标头的前 4 个字节应该是文件签名,应该是十六进制值 0x04034b50。文件中的字节顺序是相反的 - PKWARE 指定“除非另有指定,否则所有值都以小端字节顺序存储。”,因此如果您使用十六进制编辑器查看文件,您将看到 50 4b 03 04前 4 个字节。

您可以使用它来检查您的文件是否是 zip 文件。如果您在记事本中打开该文件,您会注意到前两个字节(50 和 4b)是 ASCII 字符 PK。


12
投票

您可以查看文件的幻数。 ZIP 存档的内容列于 ZIP 格式维基百科页面

PK\003\004 or PK\005\006


1
投票

检查文件的前几个字节是否有“幻数”。 Zip 文件以 PK (50 4B) 开头。由于 XML 文件无法以这些字符开头并且仍然有效,因此您可以相当确定文件类型。


1
投票
file

查看它是文本文件(xml)还是可执行文件(zip)。 向下滚动查看示例。


1
投票

try { LoadXmlFile(theFile);//Exception if not an xml file } catch(Exception ex) { LoadZipFile(theFile) }



1
投票

请参阅

单击此处了解 XML 规范。


1
投票
归档幻数

澄清一下,它以 50 4b 03 04 开头。

参见

http://www.pkware.com/documents/casestudies/APPNOTE.TXT

(来自 Simon P Stevens)


0
投票


0
投票

或者使用上面给出的幻数创建您自己的函数。


0
投票

您最好的选择是通读整个文件,找到

0x07064b50

(ZIP64 中央目录结束定位器签名),后跟 16 字节的任意数据,然后是

0x06054b50
(旧版 EoCD 记录签名)。
维基百科在某些时候表示 EoCD 记录位于文件的最末尾。这在技术上是正确的,但是 EoCD 记录以可变长度文本字段 

前面是其长度

结尾,并且我在规范中找不到特定的编码,所以我认为不可能推断出确切的偏移量文件末尾的签名。 如果速度慢得令人无法接受,您最好验证文件是否像有效的 XML 一样启动。这是一个非常好的启发式方法,因为

XML 文件永远不会是有效的 ZIP,因为我上面提到的标头包含禁用字符
  • <!DOCTYP
  • 并不是一种公认的魔法,而且可以肯定地说它永远不会成为一种魔法
    二进制文件格式通常使用幻数或由以签名开头的块组成,就像 ZIP 一样。尽管 ZIP 文件不一定以任何特定序列开头,但作为二进制文件,可以肯定地说它将以某些特定序列开头,而不是可能意外成为有效 XML 的用户数据。
© www.soinside.com 2019 - 2024. All rights reserved.