作者:Tony Qu
很多人会有这样的疑问,为什么新建任何一个Office文件格式初始大小永远是几k,而不是0k,既然是空的,为什么会占用空间?当初我也有这种疑问,但在研究了OLE2文档格式之后,这些疑问全部得以解开。简单的说,Office文件就是OLE2文档的一种,由于这种文档中有一些附属信息和初始结构,所以初始就是有大小的。
本文中即将提到的POIFS Browser可以到http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23409下载,它是基于NPOI项目的一个工具,专门用于分析OLE2文件格式。
什么是OLE2文档
OLE2文档,又叫ActiveX文档或Windows Compound File,它是一种广泛用于Windows平台上的格式,除了微软自己以外,很多第三方厂商也使用这种格式存放数据。虽然平时我们没有看到过.ole的文件格式,但确实有很多文件使用这种格式作为一种标准,只不过它的扩展名是.xls, .doc, .db等。一个更加常见的例子就是thumbs.db,几乎你可以在任何目录中看到这个隐藏文件,这个文件正如其名字所暗示的,就是用来存储缩略图的,其内部存了好多bmp或者jpg缩略文件,利用OLE2的灵活文件结构,它把每一个缩略图保存为一个记录,就像一个小型文件夹,如下图所示:
用POIFS Browser打开后thumbs.db,可以看到里面有4个缩略图,外加一个索引(catalog的作用纯属猜测,未经验证)。
看到这,你是不是觉得OLE2更像文件系统,确实,Windows Compound File的spec来看,这种文件格式的设计很像FAT格式。毕竟微软是做操作系统的,这方面可是微软的强项,所以那些鼓吹微软文件格式过于复杂的人,更多的是看到了表象,这也从侧面反应出了这些人的无知。
为什么.xls文件格式的初始化大小是11K
现在让我们来解开本文最初的那个疑问,之所以不是0k,是因为Office2003文件格式内部有两个默认的文档头,分别是DocumentSummaryInformation(简称DSI)和SummaryInformation(简称SI),这两个文档头中分别存储了作者(AUTHOR)、创建它的应用程序名(APPNAME)、编码页号(CODEPAGE)等信息,之所以平时我们很少关注这些信息,是因为我们很少需要这些信息,但这些信息对于文件版本管理、数据挖掘等还是很有帮助的,这也是为什么很多搜索引擎提供一些第三方文件解析器(包括OLE2文件解析器)。另外,一个默认的Excel文件通常会有三个sheet,而这三个sheet也是要占空间的,而且通常情况下里面有不少子记录。
上图,是按鼠标右键->属性,弹出的窗口,其中的详细信息有一部分就是来源于DSI和SI的,本文件的属性有作者、最后一次修改作者、公司、程序名称、最后一次保存日期等。
不同Office文件格式的区别
这一节,我们来分析一下不同的Office文件格式的区别,尽管使用了同样的文件结构,但是里面的内容还是很不同的。这里大家可以借助POIFS Browser来直观的了解这些文件格式,有好工具要学会利用。
Word文件格式 (.doc)
Word文件的内部记录比较多,有1Table(有时是0Table)、Data、WordDocument,其中WordDocument是最主要的数据记录,内部还有很多小型数据结构。CompObj是用来存储Office版本信息的,即用什么版本的Office来写的,具体数据如下:
虽然我们看不到其中的一些二进制数据,但基本的ASCII明文信息表明了这个结构的记录。
Excel文件格式 (.xls)
由于POIFS Browser能够识别Workbook记录,所以这里是用文件夹图标表示的,你可以展开它。Excel文件格式在没有VBA宏和嵌入对象的情况下是很简单的,只有Workbook和CompObj两个记录,CompObj的作用和Word文件中的是一样的,这里的Workbook存储了所有的Excel BIFF数据,内部有很多BIFF小型记录。
PowerPoint文件格式 (.ppt)
Viso文件格式 (.vsd)
请注意,以上这些文件包括的内容是最基本的,没有包括权限(Right Management)、VBA宏、加密等信息,所以其内部的记录只有4-5个,否则可能包括一大堆内部记录。这里限于篇幅,就不一一展开了。
附言
如果你有兴趣参加NPOI项目开发,为中国的开源事业做一份贡献,请与我取得联系。
参考
a. Apache POI project - http://poi.apache.org/
b. Excel Binary File Format (.xls) Structure Specification