zip文件格式

zip文件格式

说明

本人根据自己的学习过程,适当理解,并作下笔记,以便查阅。这里暂不包含zip64部分。

整体结构

简单归纳总结下,zip文件格式由文件数据区、中央目录结构,中央目录结束标志组成。其中中央目录结束节又有一个字段保存了中央目录结构的偏移。整体结构如下图

zip文件结构

分区描述

中央目录结束标志

中央目录结束标志一般位于文件的末尾。由于它也有字段指向了中央目录开始处的偏移, 所以把它放在最前面描述。它被用来标识中央目录结束。可以通过读取它来找到中央目录并解析整个文件结构。该结构具体如下:

struct EndLocator
{
    ui32 signature;   //目录结束标记,(固定值0x06054b50)
    ui16 elDiskNumber;  //当前磁盘编号
    ui16 elStartDiskNumber;  //中央目录开始位置的磁盘编号
    ui16 elEntriesOnDisk;  //该磁盘上所记录的核心目录数量
    ui16 elEntriesInDirectory;  //中央目录结构总数
    ui32 elDirectorySize;  //中央目录的大小
    ui32 elDirectoryOffset;  //中央目录开始位置相对于文件头的偏移
    ui16 elCommentLen;  // 注释长度
    char *elComment;  // 注释内容
};
中央目录结构

中央目录结构位于文件数据区后,它用来保存所有文件的路径信息,和对应文件数据结构区在文件中的偏移。该结构具体如下:

struct DirEntry
{
    ui32 signature;  // 中央目录文件header标识(0x02014b50)
    ui16 deVersionMadeBy;  // 压缩所用的pkware版本
    ui16 deVersionToExtract;  // 解压所需pkware的最低版本
    ui16 deFlags;  // 通用位标记
    ui16 deCompression;  // 压缩方法
    ui16 deFileTime;  // 文件最后修改时间
    ui16 deFileDate;  // 文件最后修改日期
    ui32 deCrc;  // CRC-32校验码
    ui32 deCompressedSize;  // 压缩后的大小
    ui32 deUncompressedSize;  // 未压缩的大小
    ui16 deFileNameLength;  // 文件名长度
    ui16 deExtraFieldLength;  // 扩展域长度
    ui16 deFileCommentLength; // 文件注释长度
    ui16 deDiskNumberStart;  // 文件开始位置的磁盘编号
    ui16 deInternalAttributes;  // 内部文件属性
    ui32 deExternalAttributes;  // 外部文件属性
    ui32 deHeaderOffset;  // 本地文件头的相对位移
    char *deFileName;  // 目录文件名
    char *deExtraField;  // 扩展域
    char *deFileComment; // 文件注释内容
};

中央目录结构区是由中央目录结构的数组组成,这个结构只有目录文件名,扩展域,文件注释内容长度是不定的,并且可以在这个结构中获取它的长度,那么通过此就可以遍历出所有的文件。设当前中央目录结构偏移为current_offset,下个中央目录结构偏移为next_offset,则计算公式为:

next_offset = current_offset + sizeof(DirEntry) - 3*sizeof(char*) + deFileNameLength + deExtraFieldLength + deFileCommentLength;

其中CRC32校验码为对应的文件压缩数据的CRC32的校验码,如对应文件的数据压缩数据的CRC32与这里的值不同,则数据损坏。
通过中央目录结构的deHeaderOffset字段可以直接获取到对应文件的文件数据区结构的文件偏移,就可以直接获取到对应文件的压缩数据了。

文件数据区

文件数据区是保存所有压缩文件数据的区,它位于文件头,并由压缩数据结构的数组组成。其结构如下:

struct Record
{
    ui32 signature;  // 文件头标识,值固定(0x04034b50)
    ui16 frVersion;  // 解压文件所需 pkware最低版本
    ui16 frFlags;  // 通用比特标志位(置比特0位=加密)
    ui16 frCompression;  // 压缩方式
    ui16 frFileTime;  // 文件最后修改时间
    ui16 frFileDate;  //文件最后修改日期
    ui32 frCrc;  // CRC-32校验码
    ui32 frCompressedSize;  //  压缩后的大小
    ui32 frUncompressedSize;  // 未压缩的大小
    ui16 frFileNameLength;  //  文件名长度
    ui16 frExtraFieldLength;  // 扩展区长度
    char* frFileName;  // 文件名
    char* frExtraField;  // 扩展区
    char* frData; // 压缩数据
};

这里的压缩方式frCompression有如下取值:

          0 - The file is stored (no compression)
          1 - The file is Shrunk
          2 - The file is Reduced with compression factor 1
          3 - The file is Reduced with compression factor 2
          4 - The file is Reduced with compression factor 3
          5 - The file is Reduced with compression factor 4
          6 - The file is Imploded
          7 - Reserved for Tokenizing compression algorithm
          8 - The file is Deflated
          9 - Enhanced Deflating using Deflate64(tm)
         10 - PKWARE Data Compression Library Imploding
         11 - Reserved by PKWARE
         12 - File is compressed using BZIP2 algorithm

通过中央目录结构就可以找到文件数据结构,通过文件数据结构获取到压缩数据结构,并通过此结构可以获取到压缩的数据和使用的算法,并可以根据此解压出对应的数据。

crc32

crc32即循环冗余校验,一般用于校验数据是否正确。其实现方式参考http://blog.csdn.net/lickylin/article/details/7857586

总结

zip文件结构比较清晰,可以从位于文件尾的中央文件目录结束区入手,获取到中央目录结构的偏移地址,再遍历中央目录获取到所有的文件,并通过文件数据结构获取到文件数据,数据是否损坏可通过crc32进行校验。

本书讨论数据结构和算法分析。数据结构主要研究组织大量数据的方法,而算法分析则是对算法运行时间的评估。随着计算机的速度越来越快,对于能够处理大量输入数据的程序的需求变得日益急切。可是,由于在输入量很大的时候,程序的低效率现象变得非常明显,因此这又要求对效率问题给予更仔细的关注。通过在实际编程之前对算法的分析,学生可以决定一个特定的解法是否可行。例如,读者在本书中将读到一些特定的问题并看到精心的实现方法是如何把对大量数据的时间限制从16年减至不到1秒的。因此,若无运行时间的阐释,就不会有算法和数据结构的提出。   本书是国外数据结构与算法分析方在的标准教材,介绍了数据结构(大量数据的组织方法)以及算法分析(算法运行时间的估算)。本书的编写目标是同时廛授好的程序设计和算法分析技巧,使读者可以开发出具有**效率的程序。 本书可作为高级数据结构课程或研究生一年级算法分析课程的教材,使用本书需具有一些中级程序设计知识,还需要离散数学的一些背景知识。   随着速度的不断提高和存储容量的持续增长,计算机的功能日益强大,从而处理数据和解决问题的规模和复杂程度与日俱增。这不仅带来了需要认真研究的新课题,而且突出了原有数据结构和算法效率低下的缺点。程序的效率问题不是由于计算机功能的强大而受到冷落,相反地,倒是被人们提到前所未有的重视程度,因为大型问题的解决所涉及到的大容量存储和高速度运算容不得我们对效率有丝毫的忽视。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值