FAT32文件系统的FAT项只使用了32bit申的28bit,因此只能描述268435456个簇(实际上还要略小于这个值,因为这其中还包括用做结束标志及坏簇标志的保留值)。
操作系统通过检测FAT表中的表项来确定文件系统中的各个簇是否被分配使用。当我们在Windows下右击某个FAT分区查看其属性时,显示的已用空间和未用空间就是根据FAT 表统计而来。
提示:我们有时会遇到这种情况,就是查看属性时发现已用空间并没有减少,但存储的文件却不见了。这是因为某些病毒在文件或子目录的目录项中写入删除标记,但并没有清除FAT表内的簇链所至。
图3.14 跳转到FAT项
3.6 FAT32
的数据区
数据区是真正用于存储用户数据的区域。数据区紧跟在FAT2之后,被划分成一个个的簇。所有的簇从2开始依次编号。也就是说,2号簇的起始位置就是数据区的起始位置。
3.6.1 根目录
虽然原则上FAT32允许根目录位于数据区中的任何位置,但通常情况下它都是位于2号簇。也就是说,根目录大多数据区的起始处,只有为数很少的情况会位于2号簇以外的其他位置。
1.定位根目录
住FAT文件系统中,寻找第一簇(即2号簇)的位置也就是寻找数据区的开始位置,这并不是一件很容易的事,因为它并不是位于文件系统的开始处,而是位于数据区。在数据区前面是保留区域和FAT区域,这两个区域都不使用FAT表进行管理。因此,数据区以前的区域只能使用扇区地址(逻辑卷地址),而无法使用簇地址。所以说,并不是每个逻辑卷地址都相应地有·个逻辑文件系统地址,FAT文件系统就是—个很好的实例。
提示:NTFS文件系统与FAT文件系统不同,NTFS文件系统的第一簇总是起始于文件系统的第一个扇区。
要想定位一个FAT32文件系统的数据区的起始处,可以通过引导扇区中的相关参数计算得到。我们可以通过以下几个步骤进行查找和计算。
步骤1:从引导扇区的偏移0x0E-0x0F字节处得到保留扇区。 步骤2:从偏移0xl0字节处得到FAT表的个数。
步骤3:从偏移0x24-0x27字节处得到每个FAT表的大小扇区数。 步骤4:利用如下公式进行计算——
保留扇区数+每个FAT表大小扇区数×FAT表个数=数据区起始扇区号
通过以上几个步骤,我们就得到了数据区的起始位置,也就是2号簇的起始扇区号。要 想计算其他已知簇号的扇区位置,还需要由引导扇区的偏移0x0D。字节处找到每簇大小扇 区数,并使用以下公式计算——
某簇的起始扇区号=保留扇区数+每个FAT表大小扇区数×FAT表个数+(该簇簇号-2×每簇扇区数)
例如,假设一个FAT32文件系统的保留扇区数为32,有两个FAT表,每个FAT表的大 小为14984个扇区,每簇扇区数为16,则它的根目录的起始位置2 号簇,也就是数据区的起始位置位位于32+14984×2=30000 号扇区,3号簇则起始于30016 号扇区,占用30016-30032号,共16个扇区。
2.根目录分析
根目录在文件系统建立时即已被创建,其目的就是存储子目录(也称为文件夹)或文件的目录项。每个目录项的大小为32个字节。
文件系统刚刚创建,还没有存储任何数据时,根目录下没有任何内容,文件系统只是为 根目录分配了一个簇的空间(通常为2号簇),将结束标记写入该簇对应的FAT表项,表示该簇已经被分配使用。这时候,为根目录分配的空间内没有任何内容。但如果在创建文件系统时指定了卷标,则会在根目录下为其建立一个卷标目录项,该目录项占用根目录中的第一个目录项位置。
图3.15显示了一个刚刚创建的FAT32文件系统的根目录,该文件系统的卷标为“FAT32TEST”。
图3.15 新创建的FAT32分区的根目录 在根目录下新建目录或文件时,其实就是在为根目录分配的簇中为其建立目录项,如果 需要则在未分配空间中为其分配空间以存储数据内容。
不管是根目录下的目录项,还是子目录中的目录项,都具有以下基本特性:
● 为文件或子目录分配的第一个簇的簇号记录在它的目录项中,其他后续簇则由FAT 表中的FAT表链进行跟踪。
● 目录项中除记录了目录或文件的起始簇号外,还记录它的名字、大小(子目录没有大小1)、时问值等信息。
● 每个子目录或文件具有一个短文件名目录项外,还会有长文件名目录项。
● 短文件名目录项固定占用32个字节,长文件名目录项则根据需要占用1个或若干个 32字节。
● 对于同一个子目录或文件,它的长文件名目录项放存它的短文件名目录项之前,如 果长文件名目录项占用多个32字'节,则按倒序存放于短文件名目录项之前。 提示:长文件名目录的结构与短文件名目录项结构不同,详细结构我们将会在目录项部分进行介绍。
在此只是简要地介绍一下目录项的基本特性,在后面介绍目录项时会进行详细的介绍。
下面我们在根目录下新建一个子目录“子目录1”和一个文本文件“文件l.txt”,再来 看根目录的内容,如图3.16所示。
图3.16 文件和目录的目录项
由3.16可以看到,在根目录下已经为子目录“子目录1”和文件“文件l.txt”建立了目录项:
● 上面的方框中是“子目录1”的目录项,加底纹的部分为短文件名目录项,位于其上的是它的长文件名目录项。
● 下面方框中是“文件1.txt”的目录项。同样,加底纹的部分为它的短文件名目录项,位于其上的是它的长文件名目录项。
文件系统创建时只为根目录分配2号簇,也就是说只占用一个簇的大小。如果使用过程 中直接在根目录下建立了较多的子目录或文件,这些子目录和文件的目录项占据的空间已经 超出了一个簇,则会在未使用的空间中再为根目录追加分配一个簇,同时将2 号 FAT表项中的结束标记改写为指向新追加分配给根目录的簇的簇号,并在该簇号对应的FAT表项中写入结束标记。
3.6.2 子目录
我们将所有除根目录以外的目录都称为子目录,不管是根目录的子目录,还是根目录的 子目录的子目录。
在FAT32文件系统中,除根目录在在创建文件系统时即被建立并分配空间外,其他所有的子目录都是在使用过程中根据需要建立的。新建一个子目录时,在其父目录中为其建立目录项,在空闲空间中为其分配一个簇并对该簇进行清零操作,同时将这个簇号记录在它的目录项中。
提示:子目录的目录项中并不描述子目录的大小,要想知道子目录所占用的空间大小,
可以从它的目录项中获得它的起始簇号并跟踪它的FAT表链直到遇到结束标记为止。
如果在根目录下创建个子目录,我们就称这个子目录为根目录的子目录,称根目录为 该子目录的父目录。如前面我们在根目录下创建的“子目录1”即为根目录的子目录,而根 目录则是\子目录1”的父目录。同样,如果我们在“子目录1”下再创建一个子目录,那么 “子目录1”和这个子目录即为父子目录父系。 创建子目录时,在为其父目录分配的簇中建立目录项,目录项中描述子这个子目录的起 始簇号。在为子目录建立目录项的同时,也在为子目录分配的簇中,使用前两个目录项描述 它与父目录的关系。
我们以在讲述根目录部分时在根目录下创建的“子目录1”为例,看一看为其分配的簇 中记录子哪些内容,如图3 .17所示。
图3 17子目录的前两个目录项 我们可以看到,虽然该子目录下并没有再建立任何下级下目录和文件,但却在其占用的 簇空间中建立了两个目录项,第一个是“.”目录项,它描述该子目录本身的一些信息;第二个是“.”目录项,它描述的是该子目录的父目录的相关信息。通过这种方式,就在子同录和其父目录间建立起了联系。
在子目录中建立下一级下目录或文件时,为下级子目录或文件建立的目录项将从第三个 目录项开始写入。
提示:子目录和根目录的不同之处只在于根目录是在创建文件系统时建立的,如果>殳有卷标和内容,分配给根目录的簇空间内没有任何内容。 而子目录是在在储过程中根据需要由用户建立的,随着子目录建立的同时,会在为其分配的簇空间开始处建立两个目录项来描述子目录本身和其父目录的信息,以使父子目录间建立起联系。
3.6.3 目录项
在下AT32文件系统中,根据结构不同可以将目录项大致分为四种:卷标目录项、“.”目录项和“..”目录项、短文件名目录项、长文件名目录项。短文件名目录项是最重要的数据结构,其中在放着有关子目录或文件的短文件名、属性、起始簇号、时间值以及内容人小等信息。因此,我们将首先以短文件名目录项为对象介绍目录项的特性及结构,然后再介绍其他的目录项。
由于FAT文件系统将子目录看做是一种特殊的文件,所以它的目录项结构与文件目录项的结构总体上是一样的,只是属性值及文件大小的描述上有所差别(子目录不设置大小值)。因此,我们将子目录项和文件目录放在一起进行介绍。
提示:为了叙述方便,有时我们会用“文件“对子目录和文件进行统一称呼
1.短文件名目录项
短文件名目录项是FAT文件系统中非常重要的一种数据结构。之所以称其为短文件名
目录项,是因为它所记录的文件名延续子DOS时代的8.3格式,即8个字符的名字加上3个字符的扩展名:
如果文件名部分不足8个字符,用Ox20进行填充。
超过8个字符时则会被截短,因为短文件名目录项中没有足够的空间记录超出的部 分。截短的方法是取文件名的前6个字符加上了“~1”(如果有同名文件,则会依次递 增该数值),然后再加上其扩展名。
如果是子目录,则将扩展名部分用“Ox20”进行填充。
为子解决长文件名问题,FAT文件系统又增加子一种“长文件名”目录项结构。其实从 Windows 95开始,不管文件名的长度是否超过8个字符,都会同时为其创建短文件名目录项和长文件名目录项,因为短文件名不区分大小写,而长文件名则是区分大小写的。
提示:我们将在后面的部分对长文件名及其目录项进行介绍。为子叙述方便,我们将在本部分中将短文件名目录项直接称为目录项。
2.短文件名目录项的特性
每个文件或子目录部分配有-个大小为32个字节的目录项,用以描述文件或子目录的属 性、大小、起始簇号和时间日期等信息。除此以外,文件名或子目录名也记录在目录项中。 目录项还具有以下特性:
当新建一个文件或子目录时,在其父目录中为其建立目录项。因为每个目录项的大 小固定为32个字节,所以我们可以把包括根目录和子目录在内的所有目录的内容部 分看作是一个目录项的列表。所有的目录项并不是具有相同的地址,而要找到一个 目录项的位置只能用分配给文件或子目录的全名进行搜索。
目录项结构中有一个属性区域,每个文件可以设置7种属性。操作系统或者某些工 具软件可能会忽略其中的某些属性。但某些属性决定着目录项被访问的方式,所以 是不可忽略的。这些天键属性包括——
◆ “子目录”属性。用来说明该目录项是一个子目录的目录项,子目录目录项所 指向的簇空间用以存储下级子目录的目录项或文件目录项。
◆ “长文件名”属性,长文件名属性是长文件名}j录项所具有的属性,它是一种 特殊类型的目录项,我们将在“文件名”部分进行详细的介绍。
◆ 还有一个是“卷标”属性,卷标目录项具有卷标属性,卷杯目录项只占用根目 录的第一个目录项位置。
每个文件或子目录还有4个非关键性属性,这些属性是否起作I用取决于操作系统是 不是强制执行它们——
◆ 只读属性。只读属性用于限定文件只可读取而不可写入。但是Windows 98和 Windows XP 下,在具有只读属性的文件夹中可以新建文件。
◆ 隐藏属性。文件或目录被设置“隐藏”属性后,将不会显示在其所在文件夹的 内容列表内。但文件或目录的“隐藏”属性通常是通过操作系统进行设置,所 以也可以通过操作系统的某些设置对其进行查看。
◆ 系统属性。系统属性用来说明一个文件是系统文件。
◆ 存档属性。当新建一个文件或对文件内容进行写入后,Windows还会为该文件 设置一个存档属性。
每个目录项包含三个时间值,即建立时间、最后访问时间和最后修改时间—— ◆ 建立时间,精确到十分之一秒。