一.概述
- 上一篇学习了有关短流的知识:http://blog.youkuaiyun.com/lipinganq/article/details/76804850
- 接下来介绍一下目录及目录条目
二.Directory Structure - 目录结构
1.directory 是由一系列directory entries组成的一个内部控制流。
2.每一个
directory entry 指向复合文档文件中一个仓库storage或一个流stream
3.directory entry按照它们在流中出现的顺序列举
4.一个directory entry从0开始的索引叫做
directory entry identifier
(DirID)
2.1 directory entry 位置
- 只要复合文档中存在仓库storage或流stream的引用,directory entry的位置就不会改变。 这意味着storage存储或流stream的DirID永远不会改变,而不管其他对象被插入或从复合文档中移除。
- 如果一个仓库storage或流stream被删除,相应的directory entry被标记为空。
- directory的开头有一个特殊的directory entry(DirID为0),它代表为 root storage ,称其为根仓库条目 - root storage entry
2.2 仓库storage的直接成员
directory将每个仓库storage的直接成员(仓库storage和流stream)组织在一个单独的红黑树
red-black tree 中。 红黑树中的节点必须满足以下所有条件:
- 根节点为黑色。
- 红色节点的父节点为黑色。
- 从根节点到所有叶的路径包含相同数量的黑色节点。
- 节点的左子节点小于节点,右子节点较大。
但请注意,并非所有实施都遵循这些规则。 读取directory entry的最安全的方法是忽略节点颜色,并从头重新构建红黑树。
2.3 例子
- 根仓库 root storage 由 root storage entry表示,它没有parent directory entry,因此没有其他可以组织在红黑树中的entry
- root storage的所有成员(“Storage1”,“Storage2”,“Stream1”,“Stream2”,“Stream3”和“Stream4”)都插入到红黑树中。 此树的根节点 root node的DirID存储在根仓库条目 root storage entry中。
- 仓库“Storage1”包含一个成员“Stream1”,插入到单独的红黑树中, “Storage1”的目录条目directory entry包含“Stream1”的DirID。
- 仓库“Storage2”包含三个成员“Stream21”,“Stream22”和“Stream23”。 这些目录条目directory entries组织在一个单独的红黑树中。 “Storage2”的目录条目directory entry包含此树的根节点的DirID。
2.4 总结
1.每个directory entry最多包含3个DirID:
- 第一个DirID是包含此Entry的红黑树的左孩子的DirID
- 第二个DirID是包含此Entry的红黑树的右孩子的DirID
- 如果此Entry是一个仓库storage,第三个DirID是包含所有子流和子仓库sub storages的另一个红黑树的DirID
2.节点Nodes按名称进行比较,以决定它们是否成为另一个节点Node的左或右子节点
- 如果名称较短,一个节点小于另一个节点; 如果名称较长,则更大。
- 如果两个名称的长度相同,则逐个比较(不区分大小写)
例子:名称“VWXYZ”小于名称“ABCDEFG”,因为前者名称的长度较短(不管字符V大于字符A的事实)。 名称“ABCDE”小于名称“ABCFG”,因为这两个名称的长度相等,并且比较名称表明前一个名称的第四个字符小于后一个名称的第四个字符。
三. Directory Entries - 目录条目
3.1 Directory Entry Structure - 目录条目结构
1.每个目录条目
directory entry 的大小恰好是128个字节
2.从一个DirID计算目录流directory stream的偏移量的公式如下:
dir_entry_pos(DirID) = DirID ∙ 128
3. 目录条目结构directory entry structure的内容:
3.2 Starting Position of a Stream - 一个流的开始位置
1.一个directory entry记录了一个流的入口,既一个流的目录条目directory entry包含流数据第一个扇区sector或短扇区 short-sector的SecID
2.在复合文档头中定义了标准流的大小,所有小于标准流大小的流都以短流short-stream存储,从而插入到短流容器流 short-stream container stream中,在这种情况下, 短流容器流short-stream container stream中第一个短扇区 short-sector的SecID和短扇区分配表short-sector allocation table用于构建流的SecID chain
四.Time Stamp - 时间戳
1.时间戳字段是一个无符号的64位整数值,包含从1601年1月160日00:00:00(公历)起经过的时间。
2.该值的一个单位等于100纳秒(10-7秒)。 这意味着,每秒钟的时间戳等于10百万个单位
3.从时间戳计算日期时,必须尊重闰年处理的正确规则:
- 能被4整除的year是闰年;
- 能被100整除的year也可能不是闰年(例如,1900年没有闰年);
- 能被400年整除的year是闰年(例如2000年是闰年)。