逆枫゛

Qt学习群:1149411109 群文件提供博客源码,定期答疑、更新学习资料。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本文介绍NTFS的文件和目录。我将从目录在NTFS卷里的存储方式开始,然后介绍用户数据文件的细节,包括文件是怎样存储和命名的,以及文件的最大字节限制。接着我将描述文件的标准属性,最后是重解析点(reparse points),它是Windows 2000NTFS 5.0引入的新特性。

 

NTFS的目录

 

从外部结构看,NTFS组织目录的方式和FAT一样(其他许多文件系统也是如此), 即所谓的多级(hierarchical)模型或目录树(directory tree)模型。目录树的“基(base)”是根(root)目录,NTFS系统的重要元数据文件之一。在根目录里,存储了指向其他文件或目录的引用,每个子目录里又可以有任意的文件和目录,这样就形成了一个树状结构。

注意:目录(Directories)又可以称为文件夹(folders

虽然NTFS里目录树的结构与FAT的类似,它们内部的管理却不同。其中一点是,FAT里目录包含了其下文件的所有额外信息,文件本身只包含数据。而在NTFS里,文件就是属性的集合,会自己包含需要的描述信息和数据。目录同样只包含自己的信息,而不用管其下的文件。

NTFS里的所有对象都是文件,这也适用于目录。每个目录在MFT里都有一个记录,它是目录信息的主要存储地。MFT里的记录存储了目录的如下属性:

l  Header (H):这是NTFS用来管理文件或目录的数据,包括NTFS内部使用的标识序列号,指向文件或目录属性的指针,和记录空闲空间的指针。注意Header不是一个属性,而是MFT记录的头信息。

l  Standard Information Attribute (SI):这个属性是文件或目录的“标准”信息,例如创建、修改、访问时间戳,以及文件的“标准”属性(只读,隐藏等)。

l  File Name Attribute (FN):这个属性存储目录的名字。注意一个目录可以有多个名字属性,例如“常规”名字,MS-DOS兼容的短名字,或者类似POSIX的硬链接名字。

l  Index Root Attribute:这个属性包含了目录下所有文件的“标准”信息。如果文件数太多,那么就只包含部分文件的信息,其余的文件信息存储于外部的index buffer attribute里,后面会介绍。

l  Index Allocation Attribute:如果目录下的文件过多,上面的Index Root Attribute放不下,就会使用这个属性包含指向index buffer入口的指针。

l  Security Descriptor (SD) Attribute:包含目录及其内容的访问控制信息,或叫安全信息(security information)。目录的访问控制列表(ACLs Access Control Lists)和相关数据就存储于此。

简单的说,小目录可能整个存储于MFT记录里,就跟小文件一样。大目录会分成多个数据记录,由目录的Index Root Attribute来引用。NTFS使用一种特殊的方式来存储目录下的文件索引。在FAT文件系统里,这些索引是一个链表,前几个索引存储于第一个簇里,接着存储于第二个簇,等等。这种方案实现容易,但需要扫描整个链表才能找到一个文件,导致定位单个文件非常耗时,特别是很大的目录。

为了提高性能,NTFS使用了B树结构。B树是一个平衡树存储结构,源自于关系型数据库, 对它的详细介绍可能花费很多篇幅,而且网络上已有不少资源,那么我就不罗嗦了。从实践效果看,B树能使目录的索引“自动排序”,这在加入新文件的时候会带来一些花费。但是文件的搜索现在性能大大提升了,特别是对于大目录。

 

NTFS的文件和数据存储

 

从用户的眼光看,文件系统的基础是文件。文件是一些数据的集合,能包含任何东西:程序,文本,音像,记录,等等其他信息。操作系统不需辨识文件的种类,文件的使用方式依赖于解释它的应用程序。

NTFS里,文件也存储成和上面类似的方式:属性的集合。文件的数据也是属性之一,术语叫做“data”属性。注意,要理解文件是如何存储的,必须对NTFS的体系结构有所了解,最好是知道MFT的结构和原理,以及NTFS下的属性类型:驻留的和非驻留的。

NTFS里文件的存储方式依赖于文件的大小。所有文件的核心结构都基于下面的信息和属性:

l  Header (H):同上面目录的Header

l  Standard Information Attribute (SI):同上面目录的Standard Information Attribute

l  Data (Data) Attribute:这个属性存储了文件的实际内容。

l  Security Descriptor (SD) Attribute:同上面目录的Security Descriptor Attribute

除了这些基本属性,一个文件可以有很多其他属性。如果一个文件的所有属性能放进一个MFT记录,那么这个文件就全部在MFT记录里。如果文件太大,NTFS把一部分属性移出MFT记录,转化成非驻留的。具体的步骤是这样的:

1.         首先NTFS试图把整个文件放进MFT记录里。只有少数非常小的文件可能成功。

2.         如果失败,data属性转化成非驻留的。MFT里的data属性只包含指向这些数据范围(extents,又叫runs)的指针。数据范围(extents)是指存储数据若干个连续的块, 位于MFT的外面。

3.         如果文件太大,导致指向数据范围的指针也不能存储在MFT记录里,那么这些指针会变成非驻留的。这样的文件在主MFT记录(main MFT record)里没有data属性,而是有一个指向下一个MFT记录的指针,data属性在这个记录里,并存储指向数据范围的指针。

4.         如果文件继续增大,NTFS会重复这种扩展,为超大的文件创建出无限个非驻留的MFT记录,当然,只要磁盘能够容纳。由此可见,文件越大,它的存储结构也会越复杂。

数据范围(extents)是NTFS里大部分文件数据存储的地方,它由若干连续的簇组成。文件的data属性里包含了数据范围的起始簇标识,和簇的个数。起始簇标识是一个虚拟簇编号(VCNvirtual cluster number)。而“起始 + 长度“的方式意味着NTFS不用读遍每个簇才知道后面的簇在哪里,它还能减少文件碎片的产生。

 

NTFS的文件大小

 

商用程序和数据库使用Windows操作系统和FAT文件系统的最大问题之一就是文件的大小限制,有时是4GB,有时是2GB。起初它们看起来足够了,但是到现在谁都知道这远远不够。即使是我自己的机器,有时也会备份比这大得多的数据文件。

前面介绍了NTFS试图把小文件存进MFT记录里,大些的文件把数据存到扩展属性和数据范围里。这种设计允许文件的大小没有限制。实际上,NTFS下文件的大小的确没有限制,单个文件可以占用整个卷,只留下很小的MFT和其他必要的内部结构。

NTFS还应用了一些特性来优化存储非常大的文件。其中之一是文件压缩(file-based compression),降低大文件占用的磁盘空间。另一个是稀疏文件(sparse files),非常适用于那些大部分内容都是0的文件。

 

NTFS文件命名

 

微软早期的操作系统在文件命名上非常不方便,比如DOS风格的8字符文件名加3字符后缀方式——所谓的8.3标准文件名。与其他竞争对手例如UnixApple Macintosh比起来,这种方式简直不可接受!为了解决这个问题,微软决定给NTFS的文件名以充分的扩展性。

l  长度:普通文件的文件名长度最多为255Unicode字符(2字节);

l  大小写:文件名可以大小写混用,并且会被NTFS保存起来。但是访问文件的时候文件名是大小写无关的,举个例子:你命名了文件“4Q Results.doc”,当你列出这个文件时,会正确的显示“4Q Results.doc”(大小写被NTFS保存起来了)。但是你可以使用下面的任何名字引用到刚才的文件:“"4q results.doc”,“ReSulTS.dOc”,等等。

l  字符:文件名能包含任意Unicode字符,包括空格,除了这几个:? " / / < > * | :,原因是这几个字符被操作系统作为文件名的分隔符或命令操作符。

l  Unicode格式:所有的NTFS文件名都存储成Unicode格式。相比之下,传统的计算机使用ASCII码(1字节),只能辨识“最常见”的一百多个英语字符。这对于其他很多语言都是不够的,特别是亚洲国家。Unicode是一种国际性的,16-bit的字符表示方式,支持当今几乎所有的语言和符号。

有的读者也许会想起,当初Window 95VFAT文件系统引入了一种长文件名,作为附加属性。这个文件系统自动为所有长文件名生成一个8.3形式的短文件名,兼容以前的软件。NTFS也是这样做的。但是表面相似并不代表内部也是一样,VFAT只是在短文件名系统上打了一个补丁,NTFS却是从设计上就支持长文件名。

文件名存储在MFT记录的file name属性里。实际上,NTFS支持同一个文件的MFT记录里有多个file name属性,第一个是文件的“常规”文件名,第二个是MS-DOS兼容的短文件名,甚至第三个作为兼容POSIX标准的硬链接(hard links)文件名。硬链接是指同一个文件有多个名字,并位于不同的目录之下。这些链接的名字可以作为不同的file name属性。这是对UNIX灵活的命名系统的一个模仿。

 

NTFS文件属性

 

NTFS文件系统里,文件是属性的集合,属性则是各种形式的信息和数据,属性的内容由软件来解释。目录也是这样,它们只是了包含一些普通文件没有的属性,并由文件系统来解释和使用。

所有的属性都有2种不同的存储方式,依赖于属性自身的大小,即:

l  驻留属性:如果属性只需很少的存储空间,那么可以放在文件的主MFT记录里。事实上,NTFS要求某些属性必须在MFT记录里,比如文件名,创建、修改、访问时间戳等。

l  非驻留属性:如果属性需要更多的空间,那么可以存储在MFT记录外面。MFT记录里会保留指向属性数据的指针。

由于MFT记录大小有限,只有少数属性可以放在MFT记录里。许多其他属性都是非驻留的,特别是文件的data属性。非驻留的属性又有2种形式。如果指向数据的指针能放进MFT记录,那么把数据放在数据范围里(称为runextent),指向这些范围的指针放在MFT记录里。一个属性可以占用多个数据范围,每个对应一个MFT记录里的指针。如果一个属性占用的数据范围太多,导致这些指针已不能放进文件的MFT记录,那么整个data属性可以移出去,变成一个外部属性(external attribute),存储于一个或多个MFT记录里。

NTFS预定义了一些属性,称为系统属性,如下表所示:

l  Attribute List:这是一个“元属性(meta-attribute)”,即属性的属性。如果某个属性变成非驻留的,那么主MFT记录会使用Attribute List存储指向这个属性的指针;

l  Bitmap:保存簇分配信息的位图,由$Bitmap元数据文件使用;

l  Data:包含文件数据。默认情况下,文件的所有数据存储在单个data属性里,数据量再大也是一个属性。不过文件可以有多个其他数据属性,供特殊的应用程序使用;

l  Extended Attribute (EA)Extended Attribute Information:据我所知,这些属性是为了兼容OS / 2下的NTFS分区,Windows NT / 2000没有使用它们;

l  File Name (FN):文件或目录的名字。前面说过,一个文件可以有多个名字,包括“常规”名字,MS-DOS兼容的短名字,或POSIX硬链接名,等;

l  Index Root Attribute:包含一个目录下的文件索引信息。如果目录下文件很少,所有的文件索引都可以放在MFT记录里;如果文件数太多,那么MFT里只存放部分文件的索引,其余的放在外面的index buffer attributes里;

l  Index Allocation Attribute:如果一个目录下的文件太多,MFT记录会创建这个属性,包含指向外部index buffer attributes属性的指针;

l  Security Descriptor (SD)::包含文件及其内容的访问控制信息,或叫安全信息(security information)。文件的访问控制列表(ACLs Access Control Lists)和相关数据就存储于此。文件所有者和认证信息也存储于此;

l  Standard Information (SI):这个属性是文件或目录的“标准”信息,例如创建、修改、访问时间戳,以及文件的“标准”属性(只读,隐藏等)。

l  Volume NameVolume InformationVolume VersionNTFS卷的标签,版本和其他信息,由$Volume元数据文件使用。

NTFS还支持用户为文件创建自定义的属性。在这里“用户”的意义有些微妙,因为这是从微软的角度来说的——应用程序开发者。应用程序可以给文件创建自己的属性,但是NTFS文件系统的使用者不能。

 

NTFS重解析点(Reparse Points

 

Windows 2000发布的NTFS版本5里最有趣的一个属性是引入了一些特殊的文件系统功能,并应用于特定的文件或目录上。这些特殊功能使NTFS文件系统更加强大和有扩展性。这个特性的实现基础叫做重解析点(reparse points)。

重解析点的使用源于一些应用程序想把一些特殊数据存储到特殊的地方——重解析点,然后由应用程序做上特殊的标记,只允许它使用。为此文件系统引入了一个应用程序相关的特殊过滤器(application-specific filter),并与重解析点的标记关联起来。多个应用程序可以把不同的数据存储到同一个重解析点文件里,只要使用不同的标记。微软保留了几个标记为自己使用。

现在我们假设用户打算访问一个有标记的重解析点文件。当文件系统打开文件时,发现有重解析点关联到这个文件,于是“重解析”这个打开文件请求,发现与应用程序相关联的可用过滤器,并与这个重解析点进行匹配,通过后就可以把重解析点的数据传送给这个过滤器了。过滤器于是可以把这些数据用于任何途径,依赖于应用程序最初的定义。这是一个非常灵活的系统:应用程序不需关心重解析点是如何工作的,重解析点的实现细节对于用户是完全透明的。你只需简单的放入和拿出数据,其余的事情都是自动完成。这使文件系统的功能大大增强了。

微软使用重解析点在Windows 2000里实现了如下的功能:

l  符号链接(Symbolic Links):符号链接允许你创建一个指向其他地方某个文件的指针。NTFS并没有像UNIX文件系统那样实现“真正”的文件符号链接,但是从功能上重解析点完全可以模拟得一模一样。本质上,NTFS的符号链接就是一个重解析点,把对一个文件的访问转移到另一个文件身上。

l  交叉点(Junction Points):交叉点和符号链接类似,只不过对象是目录而不是文件。

l  卷装载点(Volume Mount Points):卷装载点和前2者类似,只是更进一层:它能创建对整个卷的链接。比如,你可以为可移动硬盘或其他存储介质创建卷装载点,或者让本地的不同分区(C:D:E:等等)看起来就像在一个卷里一样。这对于那些大型的CD-ROM服务器非常有用,如果没有卷装载点,它们就只能为每张磁盘人工维护一个分区字母。

l  远程存储服务器(RSSRemote Storage Server):Windows 2000的这个特性能利用一些规则来移除NTFS卷上不常用的文件,放到存档介质里(比如CD-RW或磁带)。当它把文件移出到“下线”或“半下线”的存储介质上时,RSS自动创建指向这个存档文件的重解析点,以备日后使用。

上面只是重解析点使用例子的一少部分。这个功能非常灵活,是NTFS的亮点之一:它让文件系统的功能大大增强,又不需对文件系统进行任何更改。

posted on 2014-12-18 13:59  逆枫゛  阅读(675)  评论(0编辑  收藏  举报