文档详情

复合文档结构.

最****
实名认证
店铺
DOCX
167.38KB
约13页
文档ID:116727377
复合文档结构._第1页
1/13

前言网络上,有一篇流传颇广的叫做《Excel文件格式》的资料,是英文的,老实说,这篇资料对我关于“Excel文件格式”的理解,起到启蒙的作用,但是,进一步老实说,这篇资料对于我的最终工作结果,几乎起不到任何作用这篇被广泛如获至宝收藏的资料,是基于BIFF2的,BIFF的意思是Binary Interchange File Format(二进制交换文件格式),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”的组织我想我应该谢谢他们值得一提的是,网上有人说这些文档的结构,微软官方并不公开,是一些黑客通过跟踪、分析等等整理出来,不知是真是假反正很佩服这些人的毅力。

由于我的英文实在太差,有了这些英文的文档,学习起来还是很吃力,就想,会不会有中文资料?找来找去,找到一份叫做《复合文档格式研究》的资料,作者声称是为了另一篇正在创作的《Excel文件格式研究》准备的我为什么没有先搜到这份并不奇怪,因为我在找“Excel文件格式”并不知道“复合文档”……作者声称这份中文资料为其“创作”,但扫一眼就看出来这是《compdocfileformat》的翻译,而且翻译的水平跟“金山词霸”有得一拼,被人追问“记得保存过类似的资料,所以想问一下,这是你原创还是翻译?”之下,于是退缩为“说原创是不可能的,我既不是微软的工程师,也不是世界顶尖黑客关于excel内部结构,微软是不会公开的,有关的资料也是国外一些黑客用反编译的方法推测出来的本文是在翻译的基础上,加了一些其他的内容,但都是自己写的这世道……这篇《复合文档格式研究》倒是对我的工作起到了很大的帮助作用,我还是得谢谢作者,虽然作者对原文做了大量的删节而不是“加了一些其他的内容”,连章节引用都没改,可见确实“都是自己写的”资料齐了,可以动手了不知道是因为东西方的文化差异造成的,还是我的基础实在太差,很多地方很难懂,做的过程相当痛苦。

从开始找资料到第一个Excel文件的输出,整整花了三周的时间,折腾之下,也就有了一点心得,于是决定记录下来,那得有个地方记,于是决定重开博客对于复合文档,由于并非小狮原创,也谈不上“研究”,于是叫做《复合文档学习笔记》一向,我主张不管学术本身如何晦涩,写出来,也要尽量让毫无基础的人能够看懂而且我也是个很啰嗦的人,写成文字可能就相当“冗余”但我自己又是一个很善于遗忘的人,既然是笔记,那也要预着将来自己把相关知识忘个一干二净以后再来看能看得懂,有利于自己再学习,于是就要一如既往的“啰嗦”了本文基本上按照我自己的学习经过来写,重点在我认为难懂的地方阐述自己的见解当然,你也可以认为我是在“翻译一些资料”,但我实在不敢用“翻译”二字,问题就因为“我的英文实在太差”,英文原文可能已经很详尽了,我的这一篇也可能是“添足之笔”,但我保证这是我“自己写的”原文《compdocfileformat》和《excelfileformat》都是老外牛人的心血,不敢窃为己有,提供链接:复合文档格式http://sc.openoffice.org/compdocfileformat.pdf、Excel文件格式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,以至于把硬盘文件分为“二进制文件”(或者流文件)及“文本文件”,有鉴于此,为了准备让基础薄弱如小狮者能够理解本文,是有必要就有关知识啰嗦啰嗦的但本文又不是要讲这些,只能有机会另外撰文了,本文就先假设读者已经对上述知识滚瓜烂熟了……鉴于有人称微软未公开复合文档等的文件结构,手头资料又并非微软官方文档,那么就意味官方术语可能并不存在,本文中有关术语、定义或者说法,或小狮自己的理解,或人云亦云、以讹传讹,或来源于对有关文档的翻译,小狮的翻译水平又确实有限,难免谬误,深表歉意之余,欢迎指正但谢绝引为学术依据,否则后果自负,这算是免责声明为了形象的表示复合文档的结构,以便下一步工作的校验,小狮专门为此用Delphi编写了一个名叫《复合文档查看器》的小程序,若无特别说明,本文插图均为该程序的运行结果复合文档的头部存放于文件开头的512(200h)个字节,这是固定的,头部存放的信息,基本上反映了整个文件的总体概貌小狮注:作为头部,大多数文件都用固定的字节数存放在文件的开头但这并非固定的标准,有些头部是可变长度的,有些文件的头部则存放于文件的末尾,可见,“头部”仅仅是个称谓,并不等于“开头部分”,这不是翻译的问题,英文原文写做“Header”,大约是有来由的。

如果“Header”确实又有“尾部”的意思,那就是小狮翻译水平的问题了但复合文档的“头部”确实位于文件开头的的512个字节,这就使得中华儿女们对此的理解不会有歧义,这很好!还有一句废话得讲讲,本文中涉及数字后面带个“h”的,说明是个十六进制数,如前文的200h,换算为十进制就是512有些地方直接用十六进制而没有相应的换算为十进制,其一是小狮偷懒了,其二有些数值用十进制表示,于业内人士而言,反而不好表达当然,如果读者认为我不懂换算,那我也管不了……废话讲多了,该入正题了,先看图1:图1图1是一个示例文件的头部,为了更能说明问题,我选择了一个16.4 MB那么大的文件来作为示例,为什么这么做?后面会讲到再啰嗦一下,在计算机科学中,计数一般从0开始,本文也这么做,其一是为了更像那么回事,其二在Delphi编程方便如图1所示:头部从0字节开始的8个字节,是复合文档的标识,8个字节的值依次是D0h、CFh、11h、E0h、A1h、B1h、1Ah、E1h如果这8个字节不是这些值,那么这个文件就不是复合文件,当然,刚好是这些值,那也不能说就是……8至23一共16个字节,英文原文称“Unique identifier (UID) of this file (not of interest in the following, may be all 0)”,大意是“文件唯一标识,可能全部是0”,老实说,我没搞明白这个标识有什么用,手头用来做实验的文件也没找到一个不是全0的,自己生成的文件里面添上全0也没发生过什么事故,因此个人认为,这个当它全0就行了,不用管它,因此《复合文档查看器》也没有把它显示出来。

24(18h)至25两个字节,是一个16位整数,固定值为003Eh,文件格式的修订号26(1Ah)至27两个字节,是一个16位整数,固定值为0003h,文件格式的版本号28(1Ch)至29两个字节,是一个16位整数,值为FFFEh或FEFFh,字节排序方式解释这个必须依赖WinHex,图2是WinHex打开示例文件的截图:图2(WinHex截图)图中:28(1Ch)字节的值是FEh,29(1Dh)字节的值是FFh,合起来,作为一个16位(2个字节)整数,它的值是FFFEh,这就是说,低字节在前,高字节在后其实,这个在英文原文中有举例说明(第9页,4.2 Byte Order),其中说明很详细,我就不照译了,但这对于初涉其中的同学很容易混淆,所以专门说一下另外就是,按照原文的说法,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个字节,这个值不是固定的,。

下载提示
相似文档
正为您匹配相似的精品文档