复合文档学习笔记(三)

分区表

原创:弄潮小狮

先整理一些概念:

扇区:在复合文档中:除了头部,其余存储空间被划分成大小相等的存储区域,这些区域就叫做“扇区”。

短扇区:短扇区应该是复合文档中特有的一个概念(恕我孤陋寡闻,在其他格式文件中,未见过这个概念),根据有关资料介绍及小狮本人的实践,在复合文件中,特定的一些扇区又被划分成大小相等的更小(相对于扇区)存储区域,这些区域就叫做“短扇区”。这个概念有点难理解,我在学习过程中有这样的感觉,希望通过下文的描述,可以更清晰的给读者朋友勾勒出来。

扇区编码(ID):在复合文档中,扇区按顺序进行编码,紧跟着头部的那个扇区就是第一个扇区,编号为0(从0开始编码)。 

扇区偏移量:扇区第一个字节在复合文档中的绝对位置。

短扇区偏移量:短扇区第一个字节在复合文档中的绝对位置。

分区表:是一个32位整数的数组,按下标与扇区一一对应,数组的每成员的值表示在流中紧接相对应的扇区的下一个扇区(即该扇区的后续扇区)的编号,这就形成了一个链表,将相关的扇区“串接”起来,形成一个完整的“流”。有几个特殊的值:FFFFFFFFh(-1),表示该扇区为自由扇区(未被使用);FFFFFFFEh(-2),表示链表结束(没有后续扇区);FFFFFFFDh(-3),表示该扇区被分区表使用;FFFFFFFCh(-4),表示该扇区被主分区表使用。英文原文有更详细的描述(第7页,3.2 Sector Chains and SecID Chains)。

短分区表:类似分区表,不同的是短分区表用来管理短扇区。通常,数组成员的特殊值只有FFFFFFFFh(-1)和FFFFFFFEh(-2),因为分区表及主分区表不会使用短扇区来储存。

分区表扇区:用来储存分区表的扇区,就叫做“分区表扇区”。

短分区表扇区:用来储存短分区表的扇区,就叫做“短分区表扇区”。

主分区表:主分区表主要是用来管理分区表扇区的,它与前述两种分区表有个重要的区别:前两者是“链表”的形式,主分区表是一个彻头彻尾的数组,它的每一个成员的值直接指向对应的扇区,特殊值只有FFFFFFFFh(-1)。“主分区表”这个词直接翻译于英文原文,或许这个词不够恰当,但我想不出另一个更有利于表述的词来。

主分区表扇区:用来储存主分区表的扇区,就叫“主分区表扇区”。

流:如前文所述,先贤们从西方文献中直译过来的,原文“stream”我不知道是否有其他译法,但“流”已经成为计算机科学中的一个基本术语,意思大约是“连续的数据信息”,其实我很难表述这个概念,也解释不好。便于理解起见,你可以将它当作文件系统中的一个文件来看待。

短流:流尺寸小于特定数值的流,在复合文档中,这个值通常为4096(1000h)。

目录流:用来存储目录的流,在复合文档中,这是一个特殊的流,它由复合文档直接管理,而不由目录系统管理。原因应该是它本身描绘了目录的结构,目录记录了流的入口,“由目录管理目录流的入口”,显然是行不通的。

这些概念,几乎都有个“区”字,到底哪个本身就是“区”,哪个用来管理“区”的,很容易混淆。其实英文更容易混淆,都有“sector”这个词。

如果你现在还是很难理解分区表的概念,你可以将分区表理解成一份标注复合文档存储空间的“地图”。

在复合文档中:

主分区表始于头部第76(48h)个字节,为一个32位整数的数组,至头部结束,共436个字节,可存放109个分区表扇区编码,当分区表扇区的个数不止109个的时候,就需要额外的扇区进行存放,这些“额外的扇区”就叫做“主分区表扇区”。

通常,一个扇区的大小为512个字节,那么,一个主分区表扇区就能够储存128个分区表扇区编码?实际上,每个主分区表扇区只储存127个分区表扇区编码,因为每一个主分区表扇区的最后4个字节(一个32位整数)用来存放下一个主分区表扇区的编码。这样,当分区表很大的时候,才能够将主分区表按顺序“串”起来,主分区表已经是最顶级“地图”了,它只能用这种方式来进行“串接”。

事实上,按照《复合文档学习笔记(二)-头部》中的示例(图1),在这个文件中,分区表扇区的个数有263个,头部储存109个,还有154个扇区编码需要储存,那就需要“额外的扇区”,一个主分区表扇区储存127个扇区编码,154个扇区编码就需要2个扇区来存储,即2个主分区表扇区。

有一点我没搞清楚的是,前面讲过“每一个主分区表扇区的最后4个字节(一个32位整数)用来存放下一个主分区表扇区的编码”,那么,如果分配到最后一个扇区剩下128个扇区编码,剩下一个又需要一个扇区来储存,这显然很浪费,这时候,这4个字节是否直接存放的最后一个分区表山区编码?这种情况英文原文没有提及,小狮也没有去做测试,你知道,有找一个(或者专门做一个)这样的文件,是一件痛苦的事情。

在主分区表中,每一个成员的值表示一个扇区编码,FFFFFFFFh(-1)表示该扇区是空闲扇区。

按照主分区表的顺序,将这些扇区“串起来”,逻辑上就形成一个连续的数据串(扇区偏移量的计算方法见《复合文档学习笔记(二)-头部》),这个“数据串”就是分区表。

分区表也是一个32位整数的数组,但其用法与主分区表是截然不同的,分区表按照数组下标,对应扇区,譬如:分区表的第0个成员,就对应0扇区。

每个成员的值表示紧接该扇区(下一个扇区)的扇区编码(扇区偏移量计算方法同“主分区表”),这就形成一个链表,这在英文原文中也有例子说明,这里我也简单据一个例子。

譬如:分区表的第0个成员,就对应0扇区,其值为1,就表示,在流中,紧接0扇区的下一茬数据存放在1扇区中。

链表在何处结束?当一个分区表成员的值为FFFFFFFEh(-2)时,表示“下面没有了”,链表到此结束。

还有两种特殊的扇区:值为FFFFFFFDh(-3)时,表示这个扇区被分区表占用(即分区表扇区);值为FFFFFFFCh(-4)时,表示这个扇区被主分区表占用(即主分区表扇区)。

还有一个值:FFFFFFFFh(-1),表示这个扇区是空闲扇区,这通常出现在分区表的末尾。如前例:分区表的最后100个成员,其值都是FFFFFFFFh(-1)。

短分区表也是一个32位整数的数组。第一个短分区表扇区编码由头部获得,短扇区分区表由分区表管理,获得第一个短分区表扇区编码后,通过分区表“串接”,就可获得完整的短扇区分区表。其用法与分区表类似,但短扇区偏移量寻址有点麻烦,这个将在下一篇结合“目录和目录流”进行讲述。

本篇讲起来已经很绕了,为了方便阅读,小狮将可能引起混淆的有关词汇加蓝,并下划线表示,并非URL,转载时请保留原貌,谢谢!

温馨提示: 本文最后更新于2018-09-27,至今已有2032天,某些文章具有时效性,若有错误或已失效,请在下方留言
© 版权声明
THE END
喜欢就支持一下吧❀
点赞0投币 分享
评论 抢沙发

    请登录后查看评论内容