FAT(File Allocation Table)文件系统由微软发明并持有部分专利,主要有FAT12,FAT16,FAT32,exFAT四个版本。其中FAT12和FAT16早已淡出人们的视线,FAT32在一些小容量的SD卡里面仍然能够看到,而exFAT则是微软为闪存类型的存储介质定制的FAT类文件系统,因此在U盘、SD卡甚至固态硬盘领域仍然有很大比例的使用。
FAT文件系统以簇(Cluster)为单位对文件所占据的硬盘空间进行分配。一个文件占据的硬盘存储空间总是一个或者多个簇,也就是说每个文件占用的硬盘空间大小是簇大小的整数倍。
FAT32文件系统默认情况下,一个簇的大小为4KB。
在FAT文件系统中,数据区中所有的簇都从2开始编号,每个簇都有一个自己的地址编号。默认情况下,文件系统的根目录就保存在2号簇中。
当文件占据的硬盘空间包含多个簇时,多个簇通过文件分配表中保存的簇信息记录形成一个簇链,因此一个文件所包含的多个簇在物理空间上并不需要是连续的。
文件分配表是FAT文件系统中最重要的数据结构之一。FAT实际上就是文件分配表(File Allocation Table)的英文简称。
FAT文件系统中各个文件和目录的具体内容保存在数据区域的簇中。如果一个文件所占的空间大于一个簇的大小(即4KB),则进一步通过文件分配表结构来描述如何找到后续的簇:即利用文件分配表可以找到每个文件在簇中保存所形成的簇链。目录项中记录了这个文件起始簇的编号,文件分配表中则以簇编号为索引标记同一个文件下一个簇的编号,如果当前簇是该文件的唯一或者最后一个簇,那么在这个簇编号上标记为EOF即可。因此,文件分配表中对于每个簇的标记,不仅包含了各个文件的簇链信息,还标记了这个簇的分配状态。
文件分配表中的所有FAT表项保存在FAT文件系统的FAT区中。在这个FAT区域中,针对数据区的每个簇都保存了一条FAT表项(即数据区中所有簇的分配状态信息记录),每个FAT表项实际上是一条32位长度的记录,从0号簇开始进行编号,其中0号和1号簇被系统保留用于保存特殊标志信息,不是有效的簇,2号簇是数据区第一个簇,以此类推,数据区有多少个簇,在FAT表中就有多少项FAT表项记录与之对应。

目录项是FAT文件系统中一个重要的数据结构,用于描述整个系统中的目录结构和其包含的文件之间如何归属,以及各个文件和目录在数据区所占空间的起始簇的编号。
FAT文件系统中所保存的每一个文件和目录都对应一个目录项,在这个目录项保存有文件和目录的名称、大小、文件内容所保存的起始簇编号(仅包含起始簇的编号,后续簇的编号结构在文件分配表中的簇链进行检索)以及其他的元数据信息等。因此对于FAT文件系统中的每一个文件的访问,都先要到目录项这个数据结构中找到与之对应的记录,从其中解析出来这个文件的各种元信息数据以及在文件系统中所保存的起始簇编号,再从文件分配表FAT中查找到与之对应的簇链,从而找到该文件所包含的完整数据信息。
目录项又可以分为短文件名目录项和长文件名目录项。在FAT32之前的FAT文件系统中,文件和目录对应的目录项只有短文件名目录项,每个文件和目录对应的目录项的数据结构固定为32个字节,此时文件名的命名规则为标准的8.3结构,即文件名长度最长为8个字符,扩展名最长3个字符。32个字节的短文件名目录项的结构如下:

但是,以上的短文件名目录项只能支持8.3文件名结构,无法支持长文件名。为了解决这个问题,FAT32文件系统中导入了长文件名目录项对其进行支持。因此在FAT32文件系统中,无论文件名的长短是否超过8个字符,每个文件和目录的目录项结构中都包含长文件名目录项LFN和短文件名目录项SFN两个部分,长文件名目录项占据1个或者多个32字节长度,只包含文件的名字,根据文件名的实际长短决定占据1个或者多个32字节长度;短文件名目录项仍然占据固定的32字节长度,仍然是按照上表的结构包含有文件的时间、大小、起始簇编号等信息。
FAT文件系统的一开头是整个系统的保留扇区部分(FAT32的保留扇区一般包含有32个扇区),而保留扇区区域的第一个扇区则是DOS引导扇区DBR。这个DBR的数据结构中保存了这个FAT文件系统的各种结构型信息,例如文件系统大小、位置、文件分配表的记录个数和大小等。
DBR扇区的结构如图所示:

对于没有安装操作系统的文件系统而言,DBR中所包含的BPB结构无疑是最重要的信息结构,其详细定义如下图所示:

FAT32文件系统从总体上可以分为3个部分:保留扇区(包含其起始扇区的DBR),FAT区,数据区。

如上图所示,保留扇区部分包含有32个扇区,第一个扇区是FAT文件系统的引导扇区DBR,后续的31个扇区是其余保留扇区部分。
保留扇区的32个扇区中,除了第一个扇区用于保存引导扇区DBR以外,还有个别扇区用于存储较老版本的Windows操作系统的OS引导代码的扩展部分,其他扇区都是没有用到的。
DBR扇区的细节在前面已经详细描述,不再赘述。
FAT区域紧跟在保留扇区之后,包含有两个独立的部分:FAT1和FAT2,其中FAT2是FAT1的备份,防止因为FAT1损坏的情况下整个文件系统损坏,因此FAT1和FAT2的内容通常是完全相同的。
如前所述,FAT这个数据结构的主要作用就是两个:记录各个目录和文件所占用的下一个簇的编号,从而形成簇链;以及标记各个簇的分配状态,已分配还是未分配。
FAT表格实际上就是对数据区中所包含的所有簇的分配状态和簇链结构进行跟踪和管理。
因为每个FAT表项的大小固定是32位,而数据区的簇的数量也是固定的,因此FAT区域的大小也就固定了。
紧跟在FAT区域之后的就是FAT32的数据区,这部分是真正用于保存用户数据的区域,文件系统里面目录和文件的内容都保存在数据区。如前所述,数据区按照簇为单位进行划分,每个文件或者目录的内容占用其中一个或者多个簇的存储空间。
需要注意,簇的编号是从2开始编号的,也就是说数据区第一个簇的编号就是2号。一般情况下,数据区的2号簇用于保存这个文件系统的根目录,文件系统中的所有其他目录和文件都在这个根目录下保存。
当对硬盘的分区进行FAT文件系统的格式化操作后
当在FAT32文件系统中新建目录和文件时,会首先在其父目录所在的簇中增加一个目录项结构(长文件名目录项+短文件名目录项),在其中设定文件/目录的名称、创建/修改时间、文件大小等,以及对这个新建的文件/目录分配一个未被占用的簇,把起始簇的编号写入其目录项结构;然后把这个簇对应的FAT表项设置为占用状态,并把新建文件和目录的内容写入数据区的这个簇中。
如果这个新建的目录和文件所占用的硬盘空间超过一个簇的大小,则需要在其FAT表项中写入下一个簇的编号,从而形成一个簇链用于保存完整的文件和目录。
对于文件和目录的删除操作与新建的流程类似,首先在数据区中找到要删除的文件和目录的目录项(在其父目录的簇中保存),从其中得到这个文件和目录的起始簇编号,然后在FAT表中删除这个文件和目录对应的簇链,把其对应的所有簇的FAT表项全部标记为未分配状态;然后从其父目录的簇中删除其目录项结构。
如果要删除的目录中包含有其他子目录和文件的话稍微复杂一些,不同同样是递归循环找到其包含的所有文件和叶子目录,全部删除后再逐级向上删除其父目录。

