首页 复合文档结构

复合文档结构

举报
开通vip

复合文档结构复合文档结构复合文档结构复合文档结构前言网络上,有一篇流传颇广的叫做《Excel文件格式》的资料,就是英文的,老实说,这篇资料对我关于“Excel文件格式”的理解,起到启蒙的作用,但就是,进一步老实说,这篇资料对于我的最终工作结果,几乎起不到任何作用。这篇被广泛如获至宝收藏的资料,就是基于BIFF2的,BIFF的意思就是BinaryInterchangeFileFormat(二进制交换文件格式),BIFF2版本的Excel文件并不支持“合并单元格”,这对于我的工作就是个致命的打击,无法“合并单元格”,谈何“所见即所...

复合文档结构
复合文档结构复合文档结构复合文档结构前言网络上,有一篇流传颇广的叫做《Excel文件 格式 pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载 》的资料,就是英文的,老实说,这篇资料对我关于“Excel文件格式”的理解,起到启蒙的作用,但就是,进一步老实说,这篇资料对于我的最终工作结果,几乎起不到任何作用。这篇被广泛如获至宝收藏的资料,就是基于BIFF2的,BIFF的意思就是BinaryInterchangeFileFormat(二进制交换文件格式),BIFF2版本的Excel文件并不支持“合并单元格”,这对于我的工作就是个致命的打击,无法“合并单元格”,谈何“所见即所得”?所以,我怀疑那些收藏的人,有没有认真的用过这篇资料!当然包括我,我最早得到这篇资料至今少说也有5年了,也就是到了最近实在不得不用的时候,才发现了这个问题。这也许就是人之常情,被我怀疑的同学们不必为了这个跟我急!既然这样,那就得继续找资料了……于就是找到一篇《excelfileformat》,也就是英文的,这一篇很好,从BIFF2-BIFF8,非常详尽的阐述了Excel的文件格式,老外们在这方面的态度还就是比较认真的,值得学习。但就是问题又来了,仅BIFF8版本的Excel文件支持“合并单元格”!这个问题似乎很好解决,按照BIFF8的格式来做不就行了?当然行,就是的,可以按照BIFF8的格式来做。做出来的文件也可以被Excel读取,但必须通过两次崩溃、修复后才能使用。为什么?!微软有一个“复合文档格式”,Office从97到2003都采用“复合文档格式”来组织文档,Word、Excel、PowerPoint等等,都采用这种格式来保存。据说微软最新又推出另一种格式,但就是问题不大,于我的工作,“复合文档”已经够用了。“裸”的BIFF8版本的Excel文件,用Excel来打开,可能导致读写错误,进而导致崩溃,同时Excel的修复功能能够把它修复成“复合文档”。这就是我的理解。有这样的问题,显然就是不能提交给客户的。那么就必须给Excel文件“穿上”“复合文档”的外衣,要搞定Excel文件,必须先搞定复合文档。因此,“复合文档”成了通向我的工作的第一只拦路虎(为什么说“第一只”?因为后面还有)!必须解决掉。还得找资料……于就是又找到一篇《compdocfileformat》,与前面提到的《excelfileformat》一同出自一个叫做“OpenOffice”的组织。我想我应该谢谢她们。值得一提的就是,网上有人说这些文档的结构,微软官方并不公开,就是一些黑客通过跟踪、 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 等等整理出来,不知就是真就是假。反正很佩服这些人的毅力。由于我的英文实在太差,有了这些英文的文档,学习起来还就是很吃力,就想,会不会有中文资料?找来找去,找到一份叫做《复合文档格式研究》的资料,作者声称就是为了另一篇正在创作的《Excel文件格式研究》准备的。我为什么没有先搜到这份并不奇怪,因为我在找“Excel文件格式”并不知道“复合文档”……作者声称这份中文资料为其“创作”,但扫一眼就瞧出来这就是《compdocfileformat》的翻译,而且翻译的水平跟“金山词霸”有得一拼,被人追问“记得保存过类似的资料,所以想问一下,这就是您原创还就是翻译?”之下,于就是退缩为“说原创就是不可能的,我既不就是微软的工程师,也不就是世界顶尖黑客。关于excel内部结构,微软就是不会公开的,有关的资料也就是国外一些黑客用反编译的方法推测出来的。本文就是在翻译的基础上,加了一些其她的内容,但都就是自己写的。”这世道……这篇《复合文档格式研究》倒就是对我的工作起到了很大的帮助作用,我还就是得谢谢作者,虽然作者对原文做了大量的删节而不就是“加了一些其她的内容”,连章节引用都没改,可见确实“都就是自己写的”。资料齐了,可以动手了。不知道就是因为东西方的文化差异造成的,还就是我的基础实在太差,很多地方很难懂,做的过程相当痛苦。从开始找资料到第一个Excel文件的输出,整整花了三周的时间,折腾之下,也就有了一点心得,于就是决定记录下来,那得有个地方记,于就是决定重开博客。对于复合文档,由于并非小狮原创,也谈不上“研究”,于就是叫做《复合文档学习笔记》。一向,我主张不管学术本身如何晦涩,写出来,也要尽量让毫无基础的人能够瞧懂。而且我也就是个很啰嗦的人,写成文字可能就相当“冗余”。但我自己又就是一个很善于遗忘的人,既然就是笔记,那也要预着将来自己把相关知识忘个一干二净以后再来瞧能瞧得懂,有利于自己再学习,于就是就要一如既往的“啰嗦”了。本文基本上按照我自己的学习经过来写,重点在我认为难懂的地方阐述自己的见解。当然,您也可以认为我就是在“翻译一些资料”,但我实在不敢用“翻译”二字,问题就因为“我的英文实在太差”,英文原文可能已经很详尽了,我的这一篇也可能就是“添足之笔”,但我保证这就是我“自己写的”。原文《compdocfileformat》与《excelfileformat》都就是老外牛人的心血,不敢窃为己有,提供链接:复合文档格式http://sc、openoffice、org/compdocfileformat、pdf(​http:​/​​/​sc、openoffice、org​/​compdocfileformat、pdf​)、Excel文件格式http://sc、openoffice、org/excelfileformat、pdf(​http:​/​​/​sc、openoffice、org​/​excelfileformat、pdf​)。如果您只就是想了解这些结构,而且基础及英文还行,瞧原文就可以了。如果您想要瞧中文的,而且受得了我的啰嗦,那就瞧我的。当然还要有耐心,这就是第一篇,我很忙,第二篇什么时候写就不一定了。但我想我会在忘了这些之前把它写完。头部原创:弄潮小狮从前文谈及的两份来之OpenOffice的文档瞧,《compdocfileformat》(复合文档文件格式)只有区区200来KB,《excelfileformat》(Excel文件格式)却超过1MB,瞧起来,Excel文件的结构似乎比复合文档复杂5倍?实际上,Excel文件格式相当简单,复合文档的文件格式却要复杂的多。本文很多说法来源或翻译于《compdocfileformat》一文,若无特别说明,本文所指“英文原文”即指该文。下文提及的“复合文档”均指“微软复合文档”。摆弄文件格式,于小狮来讲,历史已经不短了,如果也可以说就是资历的,那可谓“老”了。最早应该在15年前,为了在Dos下用TC显示一幅BMP图片,连猜带蒙,搞定了BMP的文件格式,如果那时候知道这样做就能够成为黑客的话,那……遐想中……接下来就就是几年前学习了一下PE,后来又搞了反汇编,顺带把com文件的格式也摸索了,熟悉我的朋友应该知道,做这些事为了一个“PB神盾”,也只就是应用在自己的一些产品上,有朋友跟我说这个东东商机大大的……又遐想……摆弄文件结构,需要一些知识准备:字节、字、整数、浮点数、结构体等等,还有数制转换、ANIS、Unicode等等……我相信很多人对这些知识已经滚瓜烂熟了,嗤之以鼻、不屑一谈。曾经有牛人由于太精通PB,以至于把硬盘文件分为“二进制文件”(或者流文件)及“文本文件”,有鉴于此,为了准备让基础薄弱如小狮者能够理解本文,就是有必要就有关知识啰嗦啰嗦的。但本文又不就是要讲这些,只能有机会另外撰文了,本文就先假设读者已经对上述知识滚瓜烂熟了……鉴于有人称微软未公开复合文档等的文件结构,手头资料又并非微软官方文档,那么就意味官方术语可能并不存在,本文中有关术语、定义或者说法,或小狮自己的理解,或人云亦云、以讹传讹,或来源于对有关文档的翻译,小狮的翻译水平又确实有限,难免谬误,深 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 歉意之余,欢迎指正。但谢绝引为学术依据,否则后果自负,这算就是免责声明。为了形象的表示复合文档的结构,以便下一步工作的校验,小狮专门为此用Delphi编写了一个名叫《复合文档查瞧器》的小程序,若无特别说明,本文插图均为该程序的运行结果。复合文档的头部存放于文件开头的512(200h)个字节,这就是固定的,头部存放的信息,基本上反映了整个文件的总体概貌。小狮注:作为头部,大多数文件都用固定的字节数存放在文件的开头。但这并非固定的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 ,有些头部就是可变长度的,有些文件的头部则存放于文件的末尾,可见,“头部”仅仅就是个称谓,并不等于“开头部分”,这不就是翻译的问题,英文原文写做“Header”,大约就是有来由的。如果“Header”确实又有“尾部”的意思,那就就是小狮翻译水平的问题了。但复合文档的“头部”确实位于文件开头的的512个字节,这就使得中华儿女们对此的理解不会有歧义,这很好!还有一句废话得讲讲,本文中涉及数字后面带个“h”的,说明就是个十六进制数,如前文的200h,换算为十进制就就是512。有些地方直接用十六进制而没有相应的换算为十进制,其一就是小狮偷懒了,其二有些数值用十进制表示,于业内人士而言,反而不好表达。当然,如果读者认为我不懂换算,那我也管不了……废话讲多了,该入正题了,先瞧图1:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hr3a&url=http:​/​​/​s2.sinaimg.cn​/​orignal​/​4d615c1bg83115c04e501"\t""_blank"​)图1图1就是一个示例文件的头部,为了更能说明问题,我选择了一个16、4MB那么大的文件来作为示例,为什么这么做?后面会讲到。再啰嗦一下,在计算机科学中,计数一般从0开始,本文也这么做,其一就是为了更像那么回事,其二在Delphi编程方便。如图1所示:头部从0字节开始的8个字节,就是复合文档的标识,8个字节的值依次就是D0h、CFh、11h、E0h、A1h、B1h、1Ah、E1h。如果这8个字节不就是这些值,那么这个文件就不就是复合文件,当然,刚好就是这些值,那也不能说就就是……8至23一共16个字节,英文原文称“Uniqueidentifier(UID)ofthisfile(notofinterestinthefollowing,maybeall0)”,大意就是“文件唯一标识,可能全部就是0”,老实说,我没搞明白这个标识有什么用,手头用来做实验的文件也没找到一个不就是全0的,自己生成的文件里面添上全0也没发生过什么事故,因此个人认为,这个当它全0就行了,不用管它,因此《复合文档查瞧器》也没有把它显示出来。24(18h)至25两个字节,就是一个16位整数,固定值为003Eh,文件格式的修订号。26(1Ah)至27两个字节,就是一个16位整数,固定值为0003h,文件格式的版本号。28(1Ch)至29两个字节,就是一个16位整数,值为FFFEh或FEFFh,字节排序方式。解释这个必须依赖WinHex,图2就是WinHex打开示例文件的截图:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hr3a&url=http:​/​​/​s13.sinaimg.cn​/​orignal​/​4d615c1bg83115d68570c"\t""_blank"​)图2(WinHex截图)图中:28(1Ch)字节的值就是FEh,29(1Dh)字节的值就是FFh,合起来,作为一个16位(2个字节)整数,它的值就是FFFEh,这就就是说,低字节在前,高字节在后。其实,这个在英文原文中有举例说明(第9页,4、2ByteOrder),其中说明很详细,我就不照译了,但这对于初涉其中的同学很容易混淆,所以专门说一下。另外就就是,按照原文的说法,FFFEh表示“Little-Endian”(这个词我不知道怎么翻译,意即低字节在前),FEFFh表示“Big-Endian”(这个词我不知道怎么翻译,意即高字节在前),那么,对于本字段而言,不管采用何种方法进行储存,其储存结果都如图2所示,这就很麻烦(其实小狮也完全搞不懂),所幸,英文原文又称“在现实应用中,只采用前者”,这就没什么问题了,我们直接把这个值固定为FFFEh,而且“Little-Endian”符合内存读写规律,省去很多转换。幸甚!幸甚!30(1Eh)至31两个字节,就是一个16位整数,值通常为9,表示一个扇区的大小,就是2的幂,值为9表示2^9,即512个字节,这个值不就是固定的,但通常就是9。扇区:英文“sector”,我不知道原文就是否有“扇形区域”的意思,但“扇区”的叫法本身有点意思,这个有机会再写,在本文中,只需要把它理解为一个“存储块”就行了。32(20h)至33两个字节,就是一个16位整数,值通常为6,表示一个短扇区的大小,就是2的幂,值为6表示2^6,即64个字节,这个值不就是固定的,但通常就是6。短扇区:英文“short-sector”,这个概念我也就是第一次接触,英文原文有解释(第12页,6、1Short-StreamContainerStream),就不翻译了,我的理解就是它“集装”(原文用了“Container”这个词)于扇区中。由此,对这两个字段用2的幂来表示就很好理解,也只有这样,只要后者不大于前者,一个扇区就刚好能够“装下”整数个短扇区。接下来从34(22h)至43共10个字节,英文原文称“Notused”,也就就是不使用,这与其她文档的表述有点区别(别的文档称“保留”),我不知道就是否就是一样的意思,也不知道这10个字节就是否真的不被使用,实际上这10个字节的值总就是0。《复合文档查瞧器》也没有把它显示出来。44(2Ch)至47四个字节,就是一个32位整数,表示分区表扇区的总数,这个值跟文件大小有关。分区表:英文原文“sectorallocationtable”(缩写SAT),意为“扇区分配表”,我把它称为“分区表”,其一就是我记得磁盘系统有这种叫法,其二就是为了下本提及时少打几个字。在复合文档中:除了头部,其余存储空间按扇区大小划分成若干个扇区(您可以发现一个复合文档的字节总数总就是512的整数倍),用分区表进行管理,而分区表本身也存储于扇区,这个字段表示用来存储分区表的扇区的总数。事实上,这种空间分配机制跟微软赖以起家的磁盘系统的分配机制极其类似。大家都知道格式化磁盘的时候有一种“快速格式化”,其实就就是重建一个磁盘分区表,仅此而已。48(30h)至51四个字节,就是一个32位整数,表示目录流第一个扇区的ID,ID这个词,用途太广泛了,在这里就是编号的意思,小狮习惯称之为“编码”。扇区编码:前面讲过,在复合文档中,除了头部,其余存储空间按扇区大小划分成若干个扇区,紧跟着头部的那个扇区就就是第一个扇区,编号为0(从0开始编码),这样,从扇区编码就可以很容易的计算出扇区相对于文件开始位置的偏移量,示例中:目录流第一个扇区的ID为1,则偏移量=头部大小(512)+扇区编码(1)×扇区大小(512)=1024(400h)。接下来52(34h)至55四个字节又就是“Notused”,不使用。《复合文档查瞧器》也没有把它显示出来。56(38h)至59四个字节,就是一个32位整数,表示最小标准流尺寸,值通常为4096(1000h),当一个流的大小不小于这个值时,采用扇区(标准流)储存,否则采用短扇区(短流)储存,我不知道这种机制的好处在哪里,但人家这样做,我想自有道理吧?在文件处理的时候,时空开销上应该能够得到优化,但我不确定。流:先贤们从西方文献中直译过来的,原文“stream”我不知道就是否有其她译法,但“流”已经成为计算机科学中的一个基本术语,意思大约就是“连续的数据信息”,其实我很难表述这个概念,也解释不好。便于理解起见,您可以将它当作文件系统中的一个文件来瞧待。60(3Ch)至63四个字节,就是一个32位整数,表示短分区表(缩写SSAT)的第一个扇区的ID,类似分区表,短分区表就是用来管理短扇区的。值为FFFFFFFFh(-1)时,表示短分区表不存在。如前所述,如果复合文档的所有“流”的大小均不小于“最小标准流尺寸”,则没有采用短扇区来储存的“流”,当然短扇区就不存在,也不需要所谓的短扇区分区表来管理。64(40h)至67四个字节,就是一个32位整数,表示短分区表扇区总数,类似分区表,短分区表也需要扇区来储存。68(44h)至71四个字节,就是一个32位整数,表示主分区表(缩写MSAT)的第一个扇区的ID。前面讲到“分区表(SAT)”、“短分区表(SSAT)”,现在又冒出了一个“主分区表(MSAT)”,后面会有一篇专门来认识它们。要理解这个字段,还得借助接下来的两个字段,先接着说……72(48h)至75四个字节,就是一个32位整数,表示主分区表的扇区总数。从76(4C)开始到头部结束,一共436个字节,为109个32位整数(可以瞧作数组),为主分区表的开头109个记录,每个记录为分区表扇区的编码(即ID)。当分区表扇区的个数(44(2Ch)至47)大于109个时,就需要另外的扇区来存储,前一个字段“主分区表的扇区总数”表示的就就是“另外的扇区”的个数,而再前一个字段“主分区表的第一个扇区的ID”就表示这“第一个另外的扇区”的编码。当分区表扇区的个数不大于109个时,整个主分区表就存储于头部,不再需要“另外的扇区”。那么,“主分区表的第一个扇区的ID”的值为FFFFFFFFh(-1),“主分区表的扇区总数”的值为0。当需要两个以上的“另外的扇区”来储存主分区表时,接下来的扇区如何寻址,下一篇再讲……拗口!早就说了,小狮就是个极为啰嗦的人,一个头部就写了这么多,后面还有不少内容,不知什么时候才就是个头。先整理一些概念:扇区:在复合文档中:除了头部,其余存储空间被划分成大小相等的存储区域,这些区域就叫做“扇区”。短扇区:短扇区应该就是复合文档中特有的一个概念(恕我孤陋寡闻,在其她格式文件中,未见过这个概念),根据有关资料介绍及小狮本人的实践,在复合文件中,特定的一些扇区又被划分成大小相等的更小(相对于扇区)存储区域,这些区域就叫做“短扇区”。这个概念有点难理解,我在学习过程中有这样的感觉,希望通过下文的描述,可以更清晰的给读者朋友勾勒出来。扇区编码(ID):在复合文档中,扇区按顺序进行编码,紧跟着头部的那个扇区就就是第一个扇区,编号为0(从0开始编码)。 扇区偏移量:扇区第一个字节在复合文档中的绝对位置。短扇区偏移量:短扇区第一个字节在复合文档中的绝对位置。分区表:就是一个32位整数的数组,按下标与扇区一一对应,数组的每成员的值表示在流中紧接相对应的扇区的下一个扇区(即该扇区的后续扇区)的编号,这就形成了一个链表,将相关的扇区“串接”起来,形成一个完整的“流”。有几个特殊的值:FFFFFFFFh(-1),表示该扇区为自由扇区(未被使用);FFFFFFFEh(-2),表示链表结束(没有后续扇区);FFFFFFFDh(-3),表示该扇区被分区表使用;FFFFFFFCh(-4),表示该扇区被主分区表使用。英文原文有更详细的描述(第7页,3、2SectorChainsandSecIDChains)。短分区表:类似分区表,不同的就是短分区表用来管理短扇区。通常,数组成员的特殊值只有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,转载时请保留原貌,谢谢!目录及目录流原创:弄潮小狮通过前面的讲述,我们已经知道了复合文档如何对存储空间进行管理,这就是远远不够的,我们不仅要知道复合文档中的数据,更要知道这些数据表达什么?又如何管理?这就就是本篇要讲述的“目录及目录流”,这也需要先整理几个概念:目录:如果说,分区表就是一份复合文档的物理地图的话,那么,目录就就是一份“逻辑地图”,它将告诉我们,在符合文档中的流就是如何被组织、被使用的,以及流的存储位置、大小等等。目录流:前面讲过,目录流就是用来储存目录的流,由复合文档直接管理。目录树:从DOS时代过来的朋友对“目录树”应该不会陌生,没见过DOS的朋友,也有比较直观的学习途径,在Windows下面,有“文件夹”(其实就就是DOS的“目录”),文件夹里面又包含文件夹、文件,这就形成了一个树形结构,从“根”到“枝”、“叶”。红黑树:事实上,我不记得上学的时候学过这个概念(或者说“数据结构”),在此之前连听都没听说过,资料显示,“红黑树”早在1978年已经面世,也许就是我上学不认真所致,惭愧!因此,在学习复合文档的时候,我又不得不花了不少时间“恶补”一课(这就是我碰到的另一只拦路虎)。要详细讲述这个概念以及实现方法等等,可能会需要很长的篇幅,但简单地说,红黑树就是二叉树的一种,有兴趣(或者有需要)的朋友可以自己找资料了解,在网上,这方面的资料不少。目录入口:英文原文“DirectoryEntry”,一个说明目录及其相关信息的结构。既然目录流由复合文档直接管理,那么,如何读取目录流?根据前面几节的描述,在头部可以找到目录流的第一个扇区的编码(ID)(见:《复合文档学习笔记(二)》图1),根据该编码,从分区表(SAT)中可以读取目录流的扇区链,见图3:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hyha&url=http:​/​​/​s5.sinaimg.cn​/​orignal​/​4d615c1bg84903bc6afd5"\t""_blank"​)图3按照目录流的扇区链的顺序,读取每个扇区的数据,“串起来”就就是目录流了。每个目录入口有128(80h)个字节,一个复合文档至少必须有一个目录(即“根入口”,RootEntry),在默认情况下,它大于短扇区尺寸(2^6),因此,目录流总就是以扇区来存储。实际上,不管短扇区尺寸如何设置,目录流不可能以短扇区来存储,这个问题本文最后会谈到。示例中读出的目录流数据见图4:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hyha&url=http:​/​​/​s5.sinaimg.cn​/​orignal​/​4d615c1bg849043b332eb"\t""_blank"​)图4(WinHex截图)从图4可以瞧到,目录流按每128个字节一个目录入口按顺序存放,以第一个目录入口为例,在128个字节的目录信息中:0(00h)至63(3Fh)共64个字节,存放目录入口名称,采用Unicode字符,就是一个0值字符终止的字符串。64(40h)至65(41h)共2个字节,就是一个16位整数,表示目录入口名称的长度(包括终止符0)。第66(42h)字节,就是一个8位整数,表示目录入口的类型:1(01h)表示目录就是一个仓(这个“仓”有点怪,英文原文为“storage”,我想可以理解为相当于一个文件夹);2(02h)表示目录就是一个流;5(05h)表示目录就是根,在复合文档,通常有且仅有一个这样的目录,并且总就是第一个,我不知道有没有例外,在我学习的过程中未确实碰到例外的情况。其她值,英文原文语焉不详,我在学习过程中也没碰到过,这里不做描述,以免以讹传讹。第67(43h)字节,就是一个8位整数,表示目录入口节点在红黑树中的颜色:0(00h)表示红色,1(01h)表示黑色。68(44h)至79(4Fh)共12个字节,就是三个32位整数,这三个整数的前两个被应用于红黑树中,按顺序分别表示左孩子的目录编码与右孩子的目录编码,值为-1(FFFFFFFFh)时表示该节点为“叶子”,这个请借助红黑树相关理论进行理解,这里不再赘述。第三个整数表示子目录红黑树的根节点,值为-1(FFFFFFFFh)时表示没有子目录(通常流目录入口这个值为-1),这个有点绕,后面专门讲一下。80(50h)至99(63h)共20个字节,英文原文未做详细解释,并且可以全0,在生成复合文档时,我将其全部填0,未出现异常,权且当作它们就是保留字节。100(64h)至115(73h)共16个字节,就是两个8个字节的时间戳,前者表示目录创建的时间,后者表示目录最后修改的时间。关于时间戳,英文原文有详细解释,并有生动示例,这里不再赘述。116(74h)至119(77h)共4个字节,就是一个32位整数,表示目录入口所表示的流的第一个扇区编码(ID),0(00000000h)表示没有。对于根目录,这个值有特殊的含义,本文末尾会有进一步的解释。120(78h)至123(7Bh)共4个字节,就是一个32位整数,表示目录入口所表示的流的尺寸,通过将这个尺寸与短扇区尺寸进行比较,可以确定该流就是就是以扇区还就是短扇区进行存储。124(7Ch)至127(7Fh)共4个字节,未使用。示例中的目录入口列表如图5:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hyha&url=http:​/​​/​s2.sinaimg.cn​/​orignal​/​4d615c1bg849047350b10"\t""_blank"​)图5 通过上述说明,我们可以整理出示例文件中的目录逻辑结构,见图6:(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hyha&url=http:​/​​/​s12.sinaimg.cn​/​orignal​/​4d615c1bg87bd0af7355b"\t""_blank"​)图6在这一节中,出现了两种树(红黑树与目录树)及两种根(根目录与根节点),在英文原文中,相关描述语焉不详(或许就是小狮的英文实在太烂),在理解上费了不少周折(也就是一只不小的拦路虎)。从图6可以瞧出,在前面的描述中,红黑树并非目录树的本身的组织形式,目录树只有一棵,它本身就就是复合文档中流的组织结构,而红黑树主要用于构造(或查找),每一个仓目录下的子目录独立构成一棵红黑树,上文目录入口中的“子目录红黑树的根节点”说法就变得很好理解了。查找或遍历目录时,从根目录(RootEntry)开始,从一棵红黑树进入另一棵红黑树,如此往复……图7就是示例文件的目录结构。(​http:​/​​/​photo.blog.sina.com.cn​/​showpic.html"\l"blogid=4d615c1b0100hyha&url=http:​/​​/​s9.sinaimg.cn​/​orignal​/​4d615c1bg87bcc17ede72"\t""_blank"​)图7另外,从图5可以瞧到,根目录的“入口扇区”(即“目录入口所表示的流的第一个扇区编码”)有一个值,从前面叙述中,我们已经知道,根目录只就是一个特殊的“仓目录”并非就是一个“流目录”,它怎么有一个“入口扇区”呢?这个问题提得好!在《复合文档学习笔记(三)》中,我介绍了扇区及短扇区,我们必须知道短扇区储存在哪些扇区中,否则无法读取有关数据……您猜对了,根目录的“入口扇区”就就是短扇区所在的扇区的第一个扇区编码,如果一个复合文档中不存在短扇区,那么该值0(00000000h)。可见,短扇区的偏移量依靠根目录的“入口扇区”来确定,这也就是前面讲过“目录流不可能以短扇区来存储”的原因了。本文很绕舌,因为要讲清楚的目录流跟搞清楚复合文件的目录流一样困难,或许小狮的学习能力及表述能力均有待提高。学习时脑痛,讲述时也脑痛,但本节终于写完了。瞧官就凑合吧!
本文档为【复合文档结构】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_072127
暂无简介~
格式:doc
大小:174KB
软件:Word
页数:0
分类:教育学
上传时间:2020-05-18
浏览量:0