三 关于目录的文件
看到这个题目,您会不会和诧异?前面我苦口婆心的告诉您,在NTFS系统说,目录也是文件,目录以文件的形式存在,那么为什么这里又要专门用一节来讨论目录呢?
3.1 目录文件的属性
我还是举前面那个例子,对于一个班来说,虽然大家都是平等的,但是班级里面有小组长,小组长和组员一样,都是人,但是,所行使的职能不同。因此,目录虽然是文件,但是目录包含的属性不同。一般来说,目录包括头属性、标准属性(0X10)、文件名属性(0X30)、索引根属性(0X90),大多数时候还会包含索引分配属性(0XA0)。
对于真实的文档来说,它的内容是它其中的文字。那么对于目录来说,它的内容应该是什么呢?
相信您可以猜到,当然是目录中包含的保存在该目录下的所有文件的信息啦 (如果您了解FAT的格式,您对这一点将会深信不疑) 。事实当然应该如此,不然目录与文件如何联系呢?目录的数据区(与文件的数据区相似)中,保存在该目录下的每一个文件都有一个项目。这个项目我们把它称作索引项,因为目录通过它索引到文件。因此,与文件的数据属性一样,目录的“数据属性”有一个新的名字叫做“索引根属性”(0X90属性)。索引根属性包括两个方面的内容。一个是该属性的头,这里我把他叫做索引头。还有一个部分是索引部分。索引部分又包括“索引项”和“索引项尾”。以下是一个目录典型的MFT。
属性头
10属性头
10属性
30属性头
30属性
90属性头(索引头)
90属性 (索引项)
索引项1
索引项2
………
00 00 00 00 00 00 00 00 10 00 00 00 02 00 00 00 (索引尾)
FF FF FF FF 82 79 47 11
表10 小目录典型MFT记录
好了现在你可以阅读下表,详细了解0X90属性中的索引头和索引部分。
偏移 大小 意义
0X00 4 属性号
0X04 4 属性长度
0X08 1 常驻标志
0X09 1 名称长度
0X0A 2 名称偏移
0X0C 2 标志(常驻属性不能压缩)
0X0E 2 属性ID
0X10 4 属性长度(不含头)
0X14 2 属性偏移
0X16 1 索引标志
0X17 1 填充
0X18 8 属性名
0X20 4 索引属性类型
0X24 4 排序规则
0X28 4 索引项分配大小
0X2C 1 每索引记录的簇数
0X2D 3 填充
0X30 4 每索引的偏移
0X34 4 索引项的总大小
0X38 4 索引项的分配
0X3C 1 标志,(0X01大索引)
0X3C 3 填充
表11 索引根属性中索引头部分结构
偏移 大小 意义
0X00 8 文件的MFT记录号
0X08 2 索引项大小
0X0A 2 名称偏移
0X0C 4 索引标志+填充
0X10 8 父目录的MFT文件参考号
0X18 8 文件创建时间
0X20 8 文件修改时间
0X28 8 文件最后修改时间
0X30 8 文件最后访问时间
0X38 8 文件分配大小
0X40 8 文件实际大小
0X48 8 文件标志
0X50 1 文件名长度(F)
0X51 1 文件名命名空间
0X52 2F 文件名(填充到8字节)
0X52+2F P
0X52 +P+2F 8 子节点索引缓存的VCL
表12 索引项结构
索引根属性就是由索引头和这一个个的索引项组成。每个索引项对应一个文件。当文件被删除,索引项也会随之消失。
那么您还记不记得,索引根属性是在MFT记录里的。当索引项越来越多,1K的空间当然无法存储该属性的。那么这个时候,NTFS系统是如何处理的呢?
也许,您会想到,它可能和数据流的方法一样。通过数据运行索引到外部的数据区。如果您想到这一层,那么恭喜您,您已经开始熟悉NTFS系统。NTFS的确是这么做的。但是,与数据属性(0X80)有一点小小的区别。它并非简单的在0X90属性中添加一个运行。这是因为目录可能很大,而通过目录查找文件需要一个有效的算法。NTFS中,系统利用B+树的方法查找文件(这是一个较为复杂的问题,后面有详细介绍)。于是,当索引项太大,不能全部存储在MFT记录中时,就会有两个附加的属性出现:索引分配属性(0XA0),用于描述B+树目录的子节点;索引位图属性(0XB0),用于描述索引分配属性使用的虚拟簇号。我需要保存在MFT外部的索引称作“外部索引”。0XA0属性的结构与0X80属性完全一致。因此您可以参见表9。我们把这种有0XA0属性的目录称作大目录。大目录的MFT记录可能如下(在此只提出重要的属性,真实的MFT记录可能还包含别的属性)
属性头
0X10属性头
0X10属性
0X30属性头
0X30属性
0X90属性头(索引头)
0X90属性 (可能为空,也可能含有子项目。为1级节点)
注意:90H属性的最后8位是它的子节点VCN,可以根据该簇号和运行定位它的子节点。
0XA0属性头
0XA0属性
0XB0属性头
0XB0属性
FF FF FF FF 82 79 47 11
表12 大目录典型MFT记录
0XA0属性的运行记录了外部索引分配的空间。目录的外部索引是以一个索引块为单位分配的(与簇的概念类似)。一般来说,一个索引块占4K的空间。索引块以“INDEX”开头,其头部的固定结构如下:
偏移 大小 意义
0X00 4 INDEX
0X04 2 更新序列号的偏移
0X06 2 更新序列号与更新数组(以字节为单位)
0X08 8 日志文件序列号
0X10 8 本索引缓存在索引分配中的VCN
0X18 4 索引项的偏移(以字节为单位,相对0x18偏移到索引项)
0X1C 4 总的索引项的大小(相对0X18偏移到结尾)
0X20 4 索引项分配大小
0X24 1 如果不是叶节点,置1,表示还有子节点
0X25 3 用0填充
0X28 2 更新序列(重要:与每扇区最后2个字节的值一致)
0X2A 2S-1 更新序列数组
表13 索引区头部结构
索引块头部之后,连接的是索引目录项,其结构与前面介绍的索引项目是一致的。这里不重复介绍。
3.2 文件的查找方式
文件的索引延展到外部是分层次的。其层级结构图如下。
理论上说,3级目录可以容纳几千个文件。已经足够满足现在的需求。
简单的介绍一下目录的生成方式。目录一定是从小目录到大目录(因为文件需要一个个的拷贝)。小目录的结构很简单,前面也已经做了详细的分析。此时再不断增加文件,目录会有以下几个步骤的变化。
1、 一级大目录(仅有一个索引块)
索引块既是叶节点。它的VCL为0。一个索引块只能存放20-30个文件。索引块中的索引项,以文件名按照字母大小排列。
2、 二级大目录(有多个索引块)
当文件继续增加,一个索引块不能满足要求,此时再增加一个索引块,VCL为1,并在0X90属性中增加一个索引项目,为了描述,我把这个项目叫做基点。仍然对所有的项目按字母大小排序,其字母比基点小的排在VCL为0的索引块中,否则排在VCL为1的索引块中。当文件继续增加,会再次开辟一个VCL为2的索引块,工作方式同上。
3、三级大目录
二级目录有一个限制,那就是,每增加一个索引块,0X90属性就要增加一个项目。而0X90属性是在MFT中,其大小有限制,因此,不能无限的扩大二级目录。此时,系统很聪明地把一个外部的索引块当做基点。索引块的头部0X24的值置1,表示不是叶节点。
NTFS的目录结构是一个很复杂的部分,总的来说是利用平衡B+树的方式来安排每一个目录项的,但是,也不是标准的。您可以借助WINHEX进一步分析NTFS的目录结构。
四 总结
现在,相信您已经对NTFS磁盘格式有一个大致的了解了,您会发现,FAT格式的是如此之简陋和无效率。想象一下,对文件的查询,NTFS的目录结构(包含排序)将会节约多少时间!
这里只是简单介绍了NTFS的底层磁盘结构,WINDOWS还为它量身定做了磁盘的自修复等功能,有兴趣的朋友还可以研究。
以下是一个转载于硅谷动力的一张表,可以很清楚地看到NTFS的优势所在。FAT唯一的优势在于它的兼容性,因为它支持微软所有的操作系统。但是,NTFS的优越性不言而喻,如果在软件的行业里真的存在一统天下的传说,那么“但随着操作系统的顺利统一,应用环境的逐步迁移,NTFS将最终一统文件系统的天下。走过这个命运的交点,两条轨迹在不远处汇成一线……”
表14 磁盘格式性能比较
比较标准 NTFS5 NTFS FAT32 FAT16
适用操作系统 Windows 2000、XP Windows NT、2000、XP Windows 98、Me、2000、XP DOS、 Windows所有版本
磁盘管理限制
最大分区尺寸 2TB 2TB 理论上2TB 2GB
分区中做多文
件数目 接近无限 接近无限 接近无限 小于65000
最大文件尺寸 决定于文件存放分区的尺寸 决定于文件存放分区的尺寸 4GB 2GB
最大簇数 几乎无限 几乎无限 268435456 65535
最大文件名长度 255个英文字符 255个英文字符 255个英文字符 8.3文件名标准, VFAT中为255个英文字符
文件系统特征 Unicode(统一代码)
文件命名 由Unicode字符设定 由Unicode字符设定 由系统字符设定 由系统字符设定
系统记录镜像 MFT镜像文件 MFT镜像文件 FAT文件表的第二拷贝 FAT文件表的第二拷贝
引导扇区位置 第一和最后的扇区 第一和最后的扇区 第一扇区 第一扇区
文件属性 标准属性加自定义属性 标准属性加自定义属性 标准属性设定 标准属性设定
交替数据流支持 支持 支持 不支持 不支持
数据压缩支持 支持 支持 不支持 不支持
数据加密支持 支持 不支持 不支持 不支持
对象标识支持 支持 支持 不支持 不支持
磁盘配额支持 支持 不支持 不支持 不支持
稀疏文件支持 支持 不支持 不支持 不支持
重装入点支持 支持 不支持 不支持 不支持
卷装入点支持 支持 不支持 不支持 不支持
性能概述
安全性构 支持 支持 不支持 不支持
可恢复性 支持 支持 不 支持 不支持
性能 在大分区上(>500MB) 在大分区上(>500MB) 在小分区上(<500MB) 在小分区上(<256MB)
性能很高但在有非常多小 性能很高但在有非常 性能较低 性能最高
文件的小分区上性能较低 多小文件的小分区
上性能较低
磁盘空间节约 最大 最大 一般 在大分区上最低
磁盘数据容错性 最大 最大 最低 一般