FAT文件系统原理的详细分析

示例源代码下载:

 http://download.csdn.net/user/retty85

 

文本结构索引:

 

图片表格索引:

1 分区表参数

2 扩展分区表项的内容

一、硬盘的物理结构

1 硬盘的物理结构

3 FAT32分区DBR的位置划分

二、硬盘的逻辑结构

2 winhex下的磁盘MBR

4 FAT32分区的BPB字段

三、磁盘引导原理

3.1 MBR扇区

 

3 winhex给出的MBR参数的意义

5 FAT32分区的扩展BPB字段

3.2 扩展分区

 

4 分区表类型标志

6 FAT16分区上的DBR组成

四、FAT分区原理

4.1 关于DBR

4.1.1 FAT32 DBR扇区

一个4分区的磁盘结构图示

7 FAT16分区的BPB字段

4.1.2 FAT16 DBR扇区

6 分区表链接图示

8 FAT16分区的扩展BPB字段

4.2  关于保留扇区

 

7 磁盘的整体结构图示

9 FAT16分区大小与对因簇大小

8 winhex下的FAT32基本分区DBR

11 FAT16目录项的定义

4.3  FAT表和数据的存储原则

4.3.1 存储过程假想

9 winhex给出的图8DBR参数说明

12 FAT32分区大小与对因簇大小

4.3.2 FAT16存储原理

10 winhex所截FAT16的文件分配表

13 FAT表的取值含义

4.3.3 FAT32存储原理

4.3.11 Fat16的组织形式

14 FAT32短文件目录项的定义

五、结束

4.3.12 Fat32的组织形式

15 FAT32长文件目录项的定义

                                          FAT文件系统原理
                         


一、硬盘的物理结构:


   
硬盘存储数据是根据电、磁转换原理实现的。硬盘由一个或几个表面镀有磁性物质的金属或玻璃等物质盘片以及盘片两面所安装的磁头和相应的控制电路组成(1),其中盘片和磁头密封在无尘的金属壳中。
硬盘工作时,盘片以设计转速高速旋转,设置在盘片表面的磁头则在电路控制下径向移动到指定位置然后将数据存储或读取出来。当系统向硬盘写入数据时,磁头中写数据电流产生磁场使盘片表面磁性物质状态发生改变,并在写电流磁场消失后仍能保持,这样数据就存储下来了;当系统从硬盘中读数据时,磁头经过盘片指定区域,盘片表面磁场使磁头产生感应电流或线圈阻抗产生变化,经相关电路处理后还原成数据。因此只要能将盘片表面处理得更平滑、磁头设计得更精密以及尽量提高盘片旋转速度,就能造出容量更大、读写数据速度更快的硬盘。这是因为盘片表面处理越平、转速越快就能越使磁头离盘片表面越近,提高读、写灵敏度和速度;磁头设计越小越精密就能使磁头在盘片上占用空间越小,使磁头在一张盘片上建立更多的磁道以存储更多的数据。


二、硬盘的逻辑结构。
    
硬盘由很多盘片(platter)组成,每个盘片的每个面都有一个读写磁头。如果有N个盘片。就有2N个面,对应2N个磁头(Heads),从012开始编号。每个盘片被划分成若干个同心圆磁道(逻辑上的,是不可见的。)每个盘片的划分规则通常是一样的。这样每个盘片的半径均为固定值R的同心圆再逻辑上形成了一个以电机主轴为轴的柱面(Cylinders),从外至里编号为012……每个盘片上的每个磁道又被划分为几十个扇区(Sector),通常的容量是512byte,并按照一定规则编号为123……形成Cylinders×Heads×Sector个扇区。这三个参数即是硬盘的物理参数。我们下面的很多实践需要深刻理解这三个参数的意义。


三、磁盘引导原理。

3.1 MBR(master boot record)扇区:
    
计算机在按下power键以后,开始执行主板bios程序。进行完一系列检测和配置以后。开始按bios中设定的系统引导顺序引导系统。假定现在是硬盘。Bios执行完自己的程序后如何把执行权交给硬盘呢。交给硬盘后又执行存储在哪里的程序呢。其实,称为mbr的一段代码起着举足轻重的作用。MBR(master boot record),即主引导记录,有时也称主引导扇区。位于整个硬盘的0柱面0磁头1扇区(可以看作是硬盘的第一个扇区)bios在执行自己固有的程序以后就会jumpmbr中的第一条指令。将系统的控制权交由mbr来执行。在总共512byte的主引导记录中,MBR的引导程序占了其中的前446个字节(偏移0H~偏移1BDH),随后的64个字节(偏移1BEH~偏移1FDH)DPT(Disk PartitionTable,硬盘分区表),最后的两个字节“55 AA”(偏移1FEH~偏移1FFH)是分区有效结束标志。
    MBR
不随操作系统的不同而不同,意即不同的操作系统可能会存在相同的MBR,即使不同,MBR也不会夹带操作系统的性质。具有公共引导的特性。
我们来分析一段mbr。下面是

winhex查看的一块希捷120GB硬盘的mbr

   你的硬盘的MBR引导代码可能并非这样。不过即使不同,所执行的功能大体是一样的。这是wowocock关于磁盘mbr的反编译,已加了详细的注释,感兴趣可以细细研究一下。
   
我们看DPT部分。操作系统为了便于用户对磁盘的管理。加入了磁盘分区的概念。即将一块磁盘逻辑划分为几块。磁盘分区数目的多少只受限于CZ的英文字母的数目,在上图DPT64个字节中如何表示多个分区的属性呢?microsoft通过链接的方法解决了这个问题。在DPT64个字节中,以16个字节为分区表项单位描述一个分区的属性。也就是说,第一个分区表项描述一个分区的属性,一般为基本分区。第二个分区表项描述除基本分区外的其余空间,一般而言,就是我们所说的扩展分区。这部分的大体说明见表1

 

2分区表第一字段

字节位移

字段长度

字段名和定义

0x01BE

BYTE

0x80

   引导指示符(Boot Indicator)  指明该分区是否是活动分区。(00为非活动分区)

0x01BF

BYTE

0x01

开始磁头(Starting Head)

0x01C0

6

0x01

开始扇区(Starting Sector) 只用了0~5位。后面的两位(6位和第7)被开始柱面字段所使用

0x01C1

10

0x00

开始柱面(Starting Cylinder)   除了开始扇区字段的最后两位外,还使用了1位来组成该柱面值。开始柱面是一个10位数,最大值为1023

0x01C2

BYTE

0x07

系统ID(System ID) 定义了分区的类型,详细定义,请参阅图4

0x01C3

BYTE

0xFE

结束磁头(Ending Head)

0x01C4

6

0xFF

结束扇区(Ending Sector)     只使用了0~5位。最后两位(67)被结束柱面字段所使用

0x01C5

10

0x7B

结束柱面(Ending Cylinder) 除了结束扇区字段最后的两位外,还使用了1位,以组成该柱面值。结束柱面是一个10位的数,最大值为1023

0x01C6

DWORD

0x0000003F

相对扇区数(Relative Sectors) 从该磁盘的开始到该分区的开始的位移量,以扇区来计算

0x01CA

DWORD

0x00DAA83D

总扇区数(Total Sectors) 该分区中的扇区总数


注:上表中的超过1字节的数据都以实际数据显示,就是按高位到地位的方式显示。存储时是按低位到高位存储的。两者表现不同,请仔细看清楚。以后出现的表,图均同。也可以在winhex中看到这些参数的意义:
   

   
说明: 每个分区表项占用16个字节,假定偏移地址从0开始。如图3的分区表项3。分区表项4同分区表项3
    1
0H偏移为活动分区是否标志,只能选00H80H80H为活动,00H为非活动。其余值对microsoft而言为非法值。
    2
、重新说明一下(这个非常重要):大于1个字节的数被以低字节在前的存储格式格式(little endian format)或称反字节顺序保存下来。低字节在前的格式是一种保存数的方法,这样,最低位的字节最先出现在十六进制数符号中。例如,相对扇区数字段的值为0x3F000000,低字节在前,实际值表示是0x0000003F。这个低字节在前的格式数的十进制数为63
    3
、系统在分区时,各分区都不允许跨柱面,即均以柱面为单位,这就是通常所说的分区粒度。有时候我们分区是输入分区的大小为7000M,分出来却是6997M,就是这个原因。 偏移2H和偏移6H的扇区和柱面参数中,扇区占6(bit),柱面占10(bit),以偏移6H为例,其低6位用作扇区数的二进制表示。其高两位做柱面数10位中的高两位,偏移7H组成的8位做柱面数10位中的低8位。由此可知,实际上用这种方式表示的分区容量是有限的,柱面和磁头从0开始编号,扇区从1开始编号,所以最多只能表示1024个柱面×63个扇区×256个磁头×512byte=8455716864byte。即通常的8.4GB(实际上应该是7.8GB左右)限制。实际上磁头数通常只用到255(由汇编语言的寻址寄存器决定),即使把这3个字节按线性寻址,依然力不从心。 在后来的操作系统中,超过8.4GB的分区其实已经不通过C/H/S的方式寻址了。而是通过偏移CH~偏移FH4个字节32位线性扇区地址来表示分区所占用的扇区总数。可知通过4个字节可以表示2^32个扇区,即2TB=2048GB,目前对于大多数计算机而言,这已经是个天文数字了。在未超过8.4GB的分区上,C/H/S的表示方法和线性扇区的表示方法所表示的分区大小是一致的。也就是说,两种表示方法是协调的。即使不协调,也以线性寻址为准。(可能在某些系统中会提示出错)。超过8.4GB的分区结束C/H/S一般填充为FEH FFH FFH。即C/H/S所能表示的最大值。有时候也会用柱面对1024的模来填充。不过这几个字节是什么其实都无关紧要了。
   
虽然现在的系统均采用线性寻址的方式来处理分区的大小。但不可跨柱面的原则依然没变。本分区的扇区总数加上与前一分区之间的保留扇区数目依然必须是柱面容量的整数倍。(保留扇区中的第一个扇区就是存放分区表的MBR或虚拟MBR的扇区,分区的扇区总数在线性表示方式上是不计入保留扇区的。如果是第一个分区,保留扇区是本分区前的所有扇区。
   
附:分区表类型标志如图4
   

3.2 扩展分区:
   
扩展分区中的每个逻辑驱动器都存在一个类似于MBR的扩展引导记录( Extended Boot Record, EBR),也有人称之为虚拟mbr或扩展mbr,意思是一样的。扩展引导记录包括一个扩展分区表和该扇区的标签。扩展引导记录将记录只包含扩展分区中每个逻辑驱动器的第一个柱面的第一面的信息。一个逻辑驱动器中的引导扇区一般位于相对扇区3263。但是,如果磁盘上没有扩展分区,那么就不会有扩展引导记录和逻辑驱动器。第一个逻辑驱动器的扩展分区表中的第一项指向它自身的引导扇区。第二项指向下一个逻辑驱动器的EBR。如果不存在进一步的逻辑驱动器,第二项就不会使用,而且被记录成一系列零。如果有附加的逻辑驱动器,那么第二个逻辑驱动器的扩展分区表的第一项会指向它本身的引导扇区。第二个逻辑驱动器的扩展分区表的第二项指向下一个逻辑驱动器的EBR。扩展分区表的第三项和第四项永远都不会被使用。
   
通过一幅4分区的磁盘结构图可以看到磁盘的大致组织形式。如图5
   

   
关于扩展分区,如图6所示,扩展分区中逻辑驱动器的扩展引导记录是一个连接表。该图显示了一个扩展分区上的三个逻辑驱动器,说明了前面的逻辑驱动器和最后一个逻辑驱动器之间在扩展分区表中的差异。

   
除了扩展分区上最后一个逻辑驱动器外,表2中所描述的扩展分区表的格式在每个逻辑驱动器中都是重复的:第一个项标识了逻辑驱动器本身的引导扇区,第二个项标识了下一个逻辑驱动器的EBR。最后一个逻辑驱动器的扩展分区表只会列出它本身的分区项。最后一个扩展分区表的第二个项到第四个项未被使用。   

   扩展分区表项的内容

扩展分区表项

分区表项的内容

第一个项

包括数据的开始地址在内的与扩展分区中当前逻辑驱动器有关的信息

第二个项

有关扩展分区中的下一个逻辑驱动器的信息,包括包含下一个逻辑驱动器的EBR的扇区的地址。如果不存在进一步的逻辑驱动器的话,该字段不会被使用

第三个项

未用

第四个项

未用

    扩展分区表项中的相对扇区数字段所显示的是从扩展分区开始到逻辑驱动器中第一个扇区的位移的字节数。总扇区数字段中的数是指组成该逻辑驱动器的扇区数目。总扇区数字段的值等于从扩展分区表项所定义的引导扇区到逻辑驱动器末尾的扇区数。

    有时候在磁盘的末尾会有剩余空间,剩余空间是什么呢?我们前面说到,分区是以1柱面的容量为分区粒度的,那么如果磁盘总空间不是整数个柱面的话,不够一个柱面的剩下的空间就是剩余空间了,这部分空间并不参与分区,所以一般无法利用。照道理说,磁盘的物理模式决定了磁盘的总容量就应该是整数个柱面的容量,为什么会有不够一个柱面的空间呢。在我的理解看来,本来现在的磁盘为了更大的利用空间,一般在物理上并不是按照外围的扇区大于里圈的扇区这种管理方式,只是为了与操作系统兼容而抽象出来CHS。可能其实际空间容量不一定正好为整数个柱面的容量吧。关于这点,如有高见,请告知http://www.sjhf.net/zymail@vip.sina.com 
四、FAT分区原理。

先来一幅结构图:
   

    现在我们着重研究FAT格式分区内数据是如何存储的。FAT分区格式是MICROSOFT最早支持的分区格式,依据FAT表中每个簇链的所占位数(有关概念,后面会讲到)分为fat12fat16fat32三种格式"变种",但其基本存储方式是相似的。
   
仔细研究图7中的fat16fat32分区的组成结构。下面依次解释DBRFAT1FAT2、根目录、数据区、剩余扇区的概念。提到的地址如无特别提示均为分区内部偏移。
4.1
关于DBR.

    DBR(DOS BOOT RECORD)即操作系统引导记录区的意思,通常占用分区的第0扇区共512个字节(特殊情况也要占用其它保留扇区,我们先说第0)。在这512个字节中,其实又是由跳转指令,厂商标志和操作系统版本号,BPB(BIOS Parameter Block),扩展BPBos引导程序,结束标志几部分组成。 以用的最多的FAT32为例说明分区DBR各字节的含义。见图8
   
8的对应解释见表3   

    3   FAT32分区上DBR中各部分的位置划分   

字节位移

字段长度

字段名

对应图8颜色

0x00

3个字节

跳转指令

 

0x03

8个字节

厂商标志和os版本号

 

0x0B

53个字节

BPB

 

0x40

26个字节

扩展BPB

 

0x5A

420个字节

引导程序代码

 

0x01FE

2个字节

有效结束标志

 

9给出了winhex对图8 DBR的相关参数解释:

   

   
根据上边图例,我们来讨论DBR各字节的参数意义。      
    MBR
CPU执行转移给引导扇区,因此,引导扇区的前三个字节必须是合法的可执行的基于x86CPU指令。这通常是一条跳转指令,该指令负责跳过接下来的几个不可执行的字节(BPB和扩展BPB),跳到操作系统引导代码部分。
   
跳转指令之后是8字节长的OEM ID,它是一个字符串, OEM ID标识了格式化该分区的操作系统的名称和版本号。为了保留与MS-DOS的兼容性,通常Windows 2000格式化该盘是在FAT16FAT32磁盘上的该字段中记录了“MSDOS 5.0”,在NTFS磁盘上(关于ntfs,另述)Windows 2000记录的是“NTFS”。通常在被Windows 95格式化的磁盘上OEM ID字段出现“MSWIN4.0”,在被Windows 95 OSR2Windows 98格式化的磁盘上OEM ID字段出现“MSWIN4.1”
   
接下来的从偏移0x0B开始的是一段描述能够使可执行引导代码找到相关参数的信息。通常称之为BPB(BIOS Parameter Block)BPB一般开始于相同的位移量,因此,标准的参数都处于一个已知的位置。磁盘容量和几何结构变量都被封在BPB之中。由于引导扇区的第一部分是一个x86跳转指令。因此,将来通过在BPB末端附加新的信息,可以对BPB进行扩展。只需要对该跳转指令作一个小的调整就可以适应BPB的变化。图9已经列出了项目的名称和取值,为了系统的研究,针对图8,将FAT32分区格式的BPB含义和扩展BPB含义释义为表格,见表4和表5

4  FAT32分区的BPB字段     

字节位移

字段长度(字节)

8对应取值

名称和定义

0x0B

2

0x0200

扇区字节数(Bytes Per Sector) 硬件扇区的大小。本字段合法的十进制值有512102420484096。对大多数磁盘来说,本字段的值为512

0x0D

1

0x08

每簇扇区数(Sectors Per Cluster),一簇中的扇区数。由于FAT32文件系统只能跟踪有限个簇(最多为4 294 967 296),因此,通过增加每簇扇区数,可以使FAT32文件系统支持最大分区数。一个分区缺省的簇大小取决于该分区的大小。本字段的合法十进制值有1248163264128Windows 2000FAT32实现只能创建最大为32GB的分区。但是,Windows 2000能够访问由其他操作系统(Windows 95OSR2及其以后的版本)所创建的更大的分区

0x0e

2

0x0020

保留扇区数(Reserved Sector) 第一个FAT开始之前的扇区数,包括引导扇区。本字段的十进制值一般为32

0x10

1

0x02

FAT(Number of FAT) 该分区上FAT的副本数。本字段的值一般为2

0x11

2

0x0000

根目录项数(Root Entries)只有FAT12/FAT16使用此字段。对FAT32分区而言,本字段必须设置为 0

0x13

2

0x0000

小扇区数(Small Sector)(只有FAT12/FAT16使用此字段)FAT32分区而言,本字段必须设置为0

0x15

1

0xF8

媒体描述符( Media Descriptor)提供有关媒体被使用的信息。值0xF8表示硬盘,0xF0表示高密度的3.5寸软盘。媒体描述符要用于MS-DOS FAT16磁盘,在Windows 2000中未被使用

0x16

2

0x0000

FAT扇区数(Sectors Per FAT)只被FAT12/FAT16所使用,FAT32分区而言,本字段必须设置为0

0x18

2

0x003F

每磁道扇区数(Sectors Per Track) 包含使用INT13h的磁盘的每道扇区数几何结构值。该分区被多个磁头的柱面分成了多个磁道

0x1A

2

0x00FF

磁头数(Number of Head) 本字段包含使用INT 13h的磁盘的磁头数几何结构值。例如,在一张1.44MB 3.5英寸的软盘上,本字段的值为 2

0x1C

4

0x0000003F

隐藏扇区数(Hidden Sector) 该分区上引导扇区之前的扇区数。在引导序列计算到根目录的数据区的绝对位移的过程中使用了该值。本字段一般只对那些在中断13h上可见的媒体有意义。在没有分区的媒体上它必须总是为0

0x20

4

0x007D043F

总扇区数(Large Sector) 本字段包含FAT32分区中总的扇区数

0x24

4

0x00001F32

FAT扇区数(Sectors Per FAT)(只被FAT32使用)该分区每个FAT所占的扇区数。计算机利用这个数和 FAT数以及隐藏扇区数(本表中所描述的)来决定根目录从哪里开始。该计算机还可以从目录中的项数决定该分区的用户数据区从哪里开始

0x28

2

0x0000

扩展标志(Extended Flag)(只被FAT32使用)该两个字节结构中各位的值为:
0-3:活动 FAT(0开始计数,而不是1).
      
只有在不使用镜像时才有效

4-6:保留
70值意味着在运行时FAT被映射到所有的FAT
     1
值表示只有一个FAT是活动的

8-15:保留

0x2A

2

0x0000

文件系统版本(File ystem Version)只供FAT32使用,高字节是主要的修订号,而低字节是次要的修订号。本字段支持将来对该FAT32媒体类型进行扩展。如果本字段非零,以前的Windows版本将不支持这样的分区

0x2C

4

0x00000002

根目录簇号(Root Cluster Number)(只供FAT32使用) 根目录第一簇的簇号。本字段的值一般为2,但不总是如此

0x30

2

0x0001

文件系统信息扇区号(File System Information SectorNumber)(只供FAT32使用) FAT32分区的保留区中的文件系统信息(File System Information, FSINFO)结构的扇区号。其值一般为1。在备份引导扇区(Backup Boot Sector)中保留了该FSINFO结构的一个副本,但是这个副本不保持更新

0x34

2

0x0006

备份引导扇区(只供FAT32使用) 为一个非零值,这个非零值表示该分区保存引导扇区的副本的保留区中的扇区号。本字段的值一般为6,建议不要使用其他值

0x36

12

12个字节均为0x00

保留(只供FAT32使用)供以后扩充使用的保留空间。本字段的值总为0



5   FAT32分区的扩展BPB字段           

字节位移

字段长度(字节)

8对应取值

字段名称和定义

0x40

1

0x80

物理驱动器号( Physical Drive Number) BIOS物理驱动器号有关。软盘驱动器被标识为0x00,物理硬盘被标识为0x80,而与物理磁盘驱动器无关。一般地,在发出一个INT13h BIOS调用之前设置该值,具体指定所访问的设备。只有当该设备是一个引导设备时,这个值才有意义

0x41

1

0x00

保留(Reserved) FAT32分区总是将本字段的值设置为0

0x42

1

0x29

扩展引导标签(Extended Boot Signature) 本字段必须要有能被Windows 2000所识别的值0x280x29

0x43

4

0x33391CFE

分区序号(Volume Serial Number) 在格式化磁盘时所产生的一个随机序号,它有助于区分磁盘

0x47

11

"NO NAME"

卷标(Volume Label) 本字段只能使用一次,它被用来保存卷标号。现在,卷标被作为一个特殊文件保存在根目录中

0x52

8

"FAT32"

系统ID(System ID) FAT32文件系统中一般取为"FAT32"



     DBR
的偏移0x5A开始的数据为操作系统引导代码。这是由偏移0x00开始的跳转指令所指向的。在图8所列出的偏移0x00~0x02的跳转指令"EB 58 90"清楚地指明了OS引导代码的偏移位置。jump 58H加上跳转指令所需的位移量,即开始于0x5A。此段指令在不同的操作系统上和不同的引导方式上,其内容也是不同的。大多数的资料上都说win98,构建于fat基本分区上的win2000,winxp所使用的DBR只占用基本分区的第0扇区。他们提到,对于fat32,一般的32个基本分区保留扇区只有第0扇区是有用的。实际上,以FAT32构建的操作系统如果是win98,系统会使用基本分区的第0扇区和第2扇区存储os引导代码;以FAT32构建的操作系统如果是win2000winxp,系统会使用基本分区的第0扇区和第0xC扇区(win2000winxp,其第0xC的位置由第0扇区的0xAB偏移指出)存储os引导代码。所以,在fat32分区格式上,如果DBR一扇区的内容正确而缺少第2扇区(win98系统)或第0xC扇区(win2000winxp系统),系统也是无法启动的。如果自己手动设置NTLDR双系统,必须知道这一点。
     DBR
扇区的最后两个字节一般存储值为0x55AADBR有效标志,对于其他的取值,系统将不会执行DBR相关指令。上面提到的其他几个参与os引导的扇区也需以0x55AA为合法结束标志。


FAT16 DBR

     FAT32
DBR的含义大致如此,对于FAT12FAT16其基本意义类似,只是相关偏移量和参数意义有小的差异,FAT格式的区别和来因,以后会说到,此处不在多说FAT12FAT16。我将FAT16的扇区参数意义列表。感兴趣的朋友自己研究一下,和FAT32大同小异的。            下图是FAT16 DBR

一个FAT16分区上的引导扇区段

字节位移

字段长度(字节)

字段名称

0x00

3

跳转指令(Jump Instruction)

0x03

8

OEM ID

0x0B

25

BPB

0x24

26

扩展BPB

0x3E

448

引导程序代码(Bootstrap Code)

0x01FE

4

扇区结束标识符(0x55AA)

 

7  FAT16分区的BPB字段     

字节位移

字段长度(字节)

例值

名称和定义

0x0B

2

0x0200

扇区字节数(Bytes Per Sector) 硬件扇区的大小。本字段合法的十进制值有512102420484096。对大多数磁盘来说,本字段的值为512

0x0D

1

0x40

每簇扇区数(Sectors Per Cluster) 一个簇中的扇区数。由于FAT16文件系统只能跟踪有限个簇(最多为65536)。因此,通过增加每簇的扇区数可以支持最大分区数。分区的缺省的簇的大小取决于该 分区的大小。本字段合法的十进制值有 1248163264128。导致簇大于32KB(每扇区字节数*每簇扇区数)的值会引起磁盘错误和软件错误

0x0e

2

0x0001

保留扇区数(Reserved Sector) 第一个FAT开始之前的扇区数,包括引导扇区。本字段的十进制值一般为1

0x10

1

0x02

FAT(Number of FAT)该分区上FAT的副本数。本字段的值一般为2

0x11

2

0x0200

根目录项数(Root Entries) 能够保存在该分区的根目录文件夹中的32个字节长的文件和文件夹名称项的总数。在一个典型的硬盘上,本字段的值为512。其中一个项常常被用作卷标号(Volume Label),长名称的文件和文件夹每个文件使用多个项。文件和文件夹项的最大数一般为511,但是如果使用的长文件名,往往都达不到这个数

0x13

2

0x0000

小扇区数(Small Sector) 该分区上的扇区数,表示为16(<65536)。对大于65536个扇区的分区来说,本字段的值为0,而使用大扇区数来取代它

0x15

1

0xF8

媒体描述符( Media Descriptor)提供有关媒体被使用的信息。值0xF8表示硬盘,0xF0表示高密度的3.5寸软盘。媒体描述符要用于MS-DOS FAT16磁盘,在Windows 2000中未被使用

0x16

2

0x00FC

FAT扇区数(Sectors Per FAT) 该分区上每个FAT所占用的扇区数。计算机利用这个数和FAT数以及隐藏扇区数来决定根目录在哪里开始。计算机还可以根据根目录中的项数(512)决定该 分区的用户数据区从哪里开始

0x18

2

0x003F

每道扇区数(Sectors Per Trark)

0x1A

2

0x0040

磁头数(Number of head)

0x1C

4

0x0000003F

隐藏扇区数(Hidden Sector) 该分区上引导扇区之前的扇区数。在引导序列计算到根目录和数据区的绝对位移的过程中使用了该值

0x20

4

0x003EF001

大扇区数(Large Sector) 如果小扇区数字段的值为0,本字段就包含该FAT16分区中的总扇区数。如果小扇区数字段的值不为0,那么本字段的值为0

 

 

8   FAT16分区的扩展BPB字段           

字节位移

字段长度(字节)

8对应取值

字段名称和定义

0x24

1

0x80

物理驱动器号( Physical Drive Number) BIOS物理驱动器号有关。软盘驱动器被标识为0x00,物理硬盘被标识为0x80,而与物理磁盘驱动器无关。一般地,在发出一个INT13h BIOS调用之前设置该值,具体指定所访问的设备。只有当该设备是一个引导设备时,这个值才有意义

0x25

1

0x00

保留(Reserved) FAT16分区一般将本字段的值设置为0

0x26

1

0x29

扩展引导标签(Extended Boot Signature) 本字段必须要有能被Windows 2000所识别的值0x280x29

0x27

4

0x52368BA8

卷序号(Volume Serial Number) 在格式化磁盘时所产生的一个随机序号,它有助于区分磁盘

0x2B

11

"NO NAME"

卷标(Volume Label) 本字段只能使用一次,它被用来保存卷标号。现在,卷标被作为一个特殊文件保存在根目录中

0x36

8

"FAT16"

文件系统类型(File System Type) 根据该磁盘格式,该字段的值可以为FATFAT12FAT16


4.2 
关于保留扇区

     在上述FAT文件系统DBR的偏移0x0E处,用2个字节存储保留扇区的数目。所谓保留扇区(有时候会叫系统扇区,隐藏扇区),是指从分区DBR扇区开始的仅为系统所有的扇区,包括DBR扇区。在FAT16文件系统中,保留扇区的数据通常设置为1,即仅仅DBR扇区。而在FAT32中,保留扇区的数据通常取为32,有时候用Partition Magic分过的FAT32分区会设置36个保留扇区,有的工具可能会设置63个保留扇区。
     FAT32
中的保留扇区除了磁盘总第0扇区用作DBR,总第2扇区(win98系统)或总第0xC扇区(win2000,winxp)用作OS引导代码扩展部分外,其余扇区都不参与操作系统管理与磁盘数据管理,通常情况下是没作用的。操作系统之所以在FAT32中设置保留扇区,是为了对DBR作备份或留待以后升级时用。FAT32中,DBR偏移0x342字节的数据指明了DBR备份扇区所在,一般为0x06,即第6扇区。当FAT32分区DBR扇区被破坏导致分区无法访问时。可以用第6扇区的原备份替换第0扇区来找回数据。


4.3  FAT
表和数据的存储原则。

     FAT(File Allocation Table 文件分配表),是MicrosoftFAT文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。假如把磁盘比作一本书,FAT表可以认为相当于书中的目录,而文件就是各个章节的内容。但FAT表的表示方法却与目录有很大的不同。
   
FAT文件系统中,文件的存储依照FAT表制定的簇链式数据结构来进行。同时,FAT文件系统将组织数据时使用的目录也抽象为文件,以简化对数据的管理。


 
存储过程假想:
   
我们模拟对一个分区存储数据的过程来说明FAT文件系统中数据的存储原则。
   
假定现在有一个空的完全没有存放数据的磁盘,大小为100KB,我们将其想象为线形的空间地址。为了存储管理上的便利,我们人为的将这100KB的空间均分成100份,每份1KB。我们来依次存储这样几个文件:A.TXT(大小10KB),B.TXT(大小53.6KB)C.TXT(大小20.5KB)
   
最起码能够想到,我们可以顺序的在这100KB空间中存放这3个文件。同时不要忘了,我们还要记下他们的大小和开始的位置,这样下次要用时才能找的到,这就像是目录。为了便于查找,我们假定用第1K的空间来存储他们的特征(属性)。还有,我们设计的存储单位是1KB,所以,A.TXT我们需要10个存储单位(为了说明方便,我们把存储单位叫做吧。也能少打点字,呵呵。)B.TXT需要54个簇,C.TXT需要21个簇。可能有人会说B.TXTC.TXT不是各自浪费了不到1簇的空间吗?干嘛不让他们紧挨着,不是省地方吗?我的回答是,如果按照这样的方式存储,目录中原本只需要记下簇号,现在还需要记下簇内的偏移,这样会增加目录的存储量,而且存取没有了规则,读取也不太方便,是得不偿失的。
   
根据上面所说的思想,我们设计了这样的图4.3.1所示的存储方式。  

4.3.1  整个100KB空间

目录

A.TXT

B.TXT

C.TXT

 

1

10

54

21

剩余14

     我们再考虑如何来写这三个文件的目录。对于每个文件而言,一定要记录的有:文件名,开始簇,大小,创建日期、时间,修改日期、时间,文件的读写属性等。这里大小能不能用结束簇来计算呢?一定不能,因为文件的大小不一定就是整数个簇的大小,否则的话像B.TXT的内容就是54KB的内容了,少了固然不行,可多了也是不行的。那么我们怎么记录呢?可以想象一下。为了管理上的方便,我们用数据库的管理方式来管理我们的目录。于是我把1KB再分成10份,假定开始簇号为0,定义每份100B的各个位置的代表含义如图4.3.2

 

4.3.2  每行100B 10(这是例子,非Fat系统)

10行记录

A.TXT

1

10

2004.3.22 10:41

2004.3.22 10:41

只读

 

 

有效记录

B.TXT

11

53.6

1949:10:1 12:0

2003.8.22 20:40

隐藏

 

C.TXT

65

20.5

2000:3:8 21:11

2005:3:8 9:11

系统

 



内容留空

 

 

 

 

 

 

 

 

文件名(50个字节)

开始簇(4个字节)

文件大小(10个字节)

创建日期、时间(10字节)

修改日期、时间(10字节)

读写属性(4字节)

保留(12字节)

 

 

             

这样设计的结构绝对可以对文件进行正确的读写了。接着让我们设计的文件系统工作吧。先改动个文件,比如A.TXT,增加点内容吧!咦?增加后往哪里放呀,虽然存储块的后面有很多空间,但紧随其后B.TXT的数据还顶着呢?要是把A.TXT移到后边太浪费处理资源,而且也不一定解决问题。这个问题看来暂时解决不了。
   
那我们换个操作,把B.txt删了,b.txt的空间随之释放。这时候空间如图4.3.3,目录如图4.3.4

 

 

 

4.3.3  整个100KB空间

目录

A.TXT

 

C.TXT

 

1

10

空白54

21

剩余14

 

 

4.3.4  每行100B 10(这是例子,非Fat系统)

10行记录

A.TXT

1

10

2004.3.22 10:41

2004.3.22 10:41

只读

 

 

 

 

 

 

 

 

 

 

C.TXT

65

20.5

2000:3:8 21:11

2005:3:8 9:11

系统

 



内容留空

 

 

 

 

 

 

 

 

文件名(50个字节)

开始簇(4个字节)

文件大小(10个字节)

创建日期、时间(10字节)

修改日期、时间(10字节)

读写属性(4字节)

保留(12字节)

 

 

            


这个操作看来还可以,我们接着做,在存入一个文件D.txt(大小为60.3KB),总共100簇的空间只用了31簇,还有68簇剩余,按说能放下。可是?往那里放呢?没有61个连续的空间了,目录行没办法写了,看来无连续块存储暂时也不行。
   
你一定能够想到我们可以在连续空间不够或增加文件长度的时候转移影响我们操作的其他文件,从而腾出空间来,但我要问你,那不是成天啥也不要干了,就是倒腾东西了吗?

    看来我们设计的文件系统有致命的漏洞,怎么解决呢?。。。。。。。。。。

    其实可以这样解决:
   
首先我们允许文件的不连续存储。目录中依然只记录开始簇和文件的大小。那么我们怎么记录文件占用那些簇呢,以文件映射簇不太方便,因为文件名是不固定的。我们换个思想,可以用簇来映射文件,在整个存储空间的前部留下几簇来记录数据区中数据与簇号的关系。对于上例因为总空间也不大,所以用前部的1Kb的空间来记录这种对应,假设3个文件都存储,空间分配如图4.3.5,同时修改一下目录,如图4.3.6

4.3.5  整个100KB空间

文件分配表

目录

A.TXT

B.TXT

C.TXT

 

0

1

2~11

12~65

66~86

87~99

 

 

4.3.6  每行100B 10(这是例子,非Fat系统)

10行记录

A.TXT

2

10

2004.3.22 10:41

2004.3.22 10:41

只读

 

 

有效记录

B.TXT

12

53.6

1949:10:1 12:0

2003.8.22 20:40

隐藏

 

C.TXT

66

20.5

2000:3:8 21:11

2005:3:8 9:11

系统

 



内容留空

 

 

 

 

 

 

 

 

文件名(50个字节)

开始簇(4个字节)

文件大小(10个字节)

创建日期、时间(10字节)

修改日期、时间(10字节)

读写属性(4字节)

保留(12字节)

 

 

              

第一簇用来记录数据区中每一簇的被占用情况,暂时称其为文件分配表。结合文件分配表和文件目录就可以达到完全的文件读取了。我们想到,把文件分配表做成一个数据表,以图4.3.7的形式记录簇与数据的对应。
 

4.3.7  文件分配表

簇号

1

2

3

...

11

12

13

...

65

66

67

...

86

87

...

99

对应数据

目录

A.TXT(1)

A.TXT(2)

...

A.TXT(10)

B.TXT(1)

B.TXT(2)

...

B.TXT(54)

C.TXT(1)

C.TXT(2)

...

C.TXT(21)

 

...

 

    用图4.3.7的组织方式是完全可以实现对文件占有簇的记录的。但还不够效率。比如文件名在文件分配表中记录太多,浪费空间,而实际上在目录中已经记录了文件的开始簇了。所以可以改良一下,用链的方式来存放占有簇的关系,变成图4.3.8的组织方式。

 

 

4.3.8  改良后的文件分配表

簇号

1

2

3

...

11

12

13

...

65

66

67

...

86

87

...

99

对应数据

目录

3

4

...

FF

13

14

...

FF

67

68

...

FF

00

...

00

    参照图4.3.8来理解一下文件分配表的意义。如文件a.txt我们根据目录项中指定的a.txt的首簇为2,然后找到文件分配表的第2簇记录,上面登记的是3,我们就能确定下一簇是3。找到文件分配表的第3簇记录,上面登记的是4,我们就能确定下一簇是4......直到指到第11簇,发现下一个指向是FF,就是结束。文件便丝毫无误读取完毕。

    我们再看上面提到的第三种情况,就是将b.txt删除以后,存入一个大小为60.3KBd.txt。利用簇链可以很容易的实现。实现后的磁盘如图4.3.9  4.3.10  4.3.11

4.3.9 整个100KB空间划分

 

文件分配表

目录

A.TXT

D.TXT

C.TXT

D.TXT

 

0

1

2~11

12~65

66~86

87~93

94~99

        

 

4.3.10 文件分配表

簇号

1

2

3

...

11

12

13

...

65

66

67

...

86

87

88

...

93

94

...

99

对应数据

目录

3

4

...

FF

13

14

...

87

67

68

...

FF

88

89

...

FF

00

...

00

 

 

4.3.11  目录 每行100B 10(这是例子,非Fat系统)

10行记录

A.TXT

2

10

2004.3.22 10:41

2004.3.22 10:41

只读

 

 

 

 

 

 

 

 

 

 

C.TXT

66

20.5

2000:3:8 21:11

2005:3:8 9:11

系统

 

D.TXT

12

60.3

1999:5:1 8:00

2003:3:20 14:0

存档

 



内容留空

 

 

 

 

 

 

 

 

文件名(50个字节)

开始簇(4个字节)

文件大小(10个字节)

创建日期、时间(10字节)

修改日期、时间(10字节)

读写属性(4字节)

保留(12字节)

 

 

    上面是我们对文件存储的一种假设,也该揭开谜底的时候了。上面的思想其实就是fat文件系统的思想的精髓(但并不是,尤其像具体的参数的意义与我们所举的例子是完全不同的。请忘掉上边细节,努力记忆下边)


FAT16存储原理:   

    当把一部分磁盘空间格式化为fat文件系统时,fat文件系统就将这个分区当成整块可分配的区域进行规划,以便于数据的存储。一般来讲,其划分形式如图7所示。我们把FAT16部分提取出来,详细描述一下:
    FAT16
Microsoft较早推出的文件系统,具有高度兼容性,目前仍然广泛应用于个人电脑尤其是移动存储设备中,FAT16简单来讲由图4.3.12所示的6部分组成(主要是前5部分)。引导扇区(DBR)我们已经说过,FAT16DBR之后没有留有任何保留扇区,其后紧随的便是FAT表。FAT表是FAT16用来记录磁盘数据区簇链结构的。像前面我们说过的例子一样,FAT将磁盘空间按一定数目的扇区为单位进行划分,这样的单位称为簇。通常情况下,每扇区512字节的原则是不变的。簇的大小一般是2n (n为整数)个扇区的大小,像512B,1K,2K,4K,8K,16K,32K64K。实际中通常不超过32K 之所以簇为单位而不以扇区为单位进行磁盘的分配,是因为当分区容量较大时,采用大小为512B的扇区管理会增加fat表的项数,对大文件存取增加消耗,文件系统效率不高。分区的大小和簇的取值是有关系的,见表9  

4.3.12 Fat16的组织形式

引导扇区

FAT1

FAT2(重复的)

根文件夹

其他文件夹及所有文件

剩余扇区

1扇区

实际情况取大小

FAT1

32个扇区

开始簇编号(2开始)

不足一簇

 

 

 

 

9  FAT16分区大小与对应簇大小

分区空间大小

每个簇的扇区

簇空间大小

0MB-32MB

1

512个字节

33MB-64MB

2

1k

65MB-128MB

4

2k

129MB-225MB

8

4k

256MB-511MB

16

8k

512MB-1023MB

32

16k

1024MB-2047MB

64

32k

2048MB-4095MB

128

64k


   
注意:少于32680个扇区的分区中,簇空间大小可最多达到每个簇8个扇区。不管用户是使用磁盘管理器来格式化分区,还是使用命令提示行键入format命令格式化,格式化程序都创建一个12位的FAT。少于16MB的分区,系统通常会将其格式化成12位的FATFAT12FAT的初始实现形式,是针对小型介质的。FAT12文件分配表要比FAT16FAT32的文件分配表小,因为它对每个条目使用的空间较少。这就给数据留下较多的空间。所有用FAT12格式化的5.25英寸软盘以及1.44MB3.5英寸软盘都是由FAT12格式化的。除了FAT表中记录每簇链结的二进制位数与FAT16不同外,其余原理与FAT16均相同,不再单独解释。。。

    格式化FAT16分区时,格式化程序根据分区的大小确定簇的大小,然后根据保留扇区的数目、根目录的扇区数目、数据区可分的簇数与FAT表本身所占空间 来确定FAT表所需的扇区数目,然后将计算后的结果写入DBR的相关位置。
    FAT16 DBR
参数的偏移0x11处记录了根目录所占扇区的数目。偏移0x16记录了FAT表所占扇区的数据。偏移0x10记录了FAT表的副本数目。系统在得到这几项参数以后,就可以确定数据区的开始扇区偏移了。
    FAT16
文件系统从根目录所占的32个扇区之后的第一个扇区开始以簇为单位进行数据的处理,这之前仍以扇区为单位。对于根目录之后的第一个簇,系统并不编号为第0簇或第1 (可能是留作关键字的原因吧),而是编号为第2簇,也就是说数据区顺序上的第1个簇也是编号上的第2簇。
    FAT
文件系统之所以有121632不同的版本之分,其根本在于FAT表用来记录任意一簇链接的二进制位数。以FAT16为例,每一簇在FAT表中占据2字节(二进制16)。所以,FAT16最大可以表示的簇号为0xFFFF(十进制的65535),以32K为簇的大小的话,FAT32可以管理的最大磁盘空间为:32KB×65535=2048MB,这就是为什么FAT16不支持超过2GB分区的原因。
    FAT
表实际上是一个数据表,以2个字节为单位,我们暂将这个单位称为FAT记录项,通常情况其第12个记录项(4个字节)用作介质描述。从第三个记录项开始记录除根目录外的其他文件及文件夹的簇链情况。根据簇的表现情况FAT用相应的取值来描述,见表10

10 FAT16记录项的取值含义(16进制)

FAT16记录项的取值

对应簇的表现情况

0000

未分配的簇

0002~FFEF

已分配的簇

FFF0~FFF6

系统保留

FFF7

坏簇

FFF8~FFFF

文件结束簇

     看一幅在winhex所截FAT16的文件分配表,图10

 

  

  
如图,FAT表以"F8 FF FF FF" 开头,此2字节为介质描述单元,并不参与FAT表簇链关系。小红字标出的是FAT扇区每2字节对应的簇号。
  
相对偏移0x4~0x5偏移为第2(顺序上第1),此处为FF,表示存储在第2簇上的文件(目录)是个小文件,只占用1个簇便结束了。
  
3簇中存放的数据是0x0005,这是一个文件或文件夹的首簇。其内容为第5簇,就是说接下来的簇位于第5—— FAT表指引我们到达FAT表的第5簇指向,上面写的数据是"FF FF",意即此文件到此簇已至结尾。
  
4簇中存放的数据是0x0006,这又是一个文件或文件夹的首簇。其内容为第6簇,就是说接下来的簇位于第6——FAT表指引我们到达FAT表的第6簇指向,上面写的数据是0x0007,就是说接下来的簇位于第7——FAT表指引我们到达FAT表的第7簇指向……直到根据FAT链读取到扇区相对偏移0x1A~0x1B,也就是第13簇,上面写的数据是0x000E,也就是指向第14——14簇的内容为"FF FF",意即此文件到此簇已至结尾。
   
后面的FAT表数据与上面的道理相同。不再分析。

    FAT表记录了磁盘数据文件的存储链表,对于数据的读取而言是极其重要的,以至于Microsoft为其开发的FAT文件系统中的FAT表创建了一份备份,就是我们看到的FAT2FAT2FAT1的内容通常是即时同步的,也就是说如果通过正常的系统读写对FAT1做了更改,那么FAT2也同样被更新。如果从这个角度来看,系统的这个功能在数据恢复时是个天灾。

    FAT文件系统的目录结构其实是一颗有向的从根到叶的树,这里提到的有向是指对于FAT分区内的任一文件(包括文件夹),均需从根目录寻址来找到。可以这样认为:目录存储结构的入口就是根目录。
    FAT
文件系统根据根目录来寻址其他文件(包括文件夹),故而根目录的位置必须在磁盘存取数据之前得以确定。FAT文件系统就是根据分区的相关DBR参数与DBR中存放的已经计算好的FAT(2)的大小来确定的。格式化以后,根目录的大小和位置其实都已经确定下来了:位置紧随FAT2之后,大小通常为32个扇区。根目录之后便是数据区第2簇。
    FAT
文件系统的另一个重要思想是把目录(文件夹)当作一个特殊的文件来处理,FAT32甚至将根目录当作文件处理(旁:NTFS将分区参数、安全权限等好多东西抽象为文件更是这个思想的升华),在FAT16中,虽然根目录地位并不等同于普通的文件或者说是目录,但其组织形式和普通的目录(文件夹)并没有不同。FAT分区中所有的文件夹(目录)文件,实际上可以看作是一个存放其他文件(文件夹)入口参数的数据表。所以目录的占用空间的大小并不等同于其下所有数据的大小,但也不等同于0。通常是占很小的空间的,可以看作目录文件是一个简单的二维表文件。其具体存储原理是:
   
不管目录文件所占空间为多少簇,一簇为多少字节。系统都会以32个字节为单位进行目录文件所占簇的分配。这32个字节以确定的偏移来定义本目录下的一个文件(或文件夹)的属性,实际上是一个简单的二维表。
   
32个字节的各字节偏移定义如表11

 

 

 

11   FAT16目录项32个字节的表示定义

字节偏移(16进制)

字节数

定义

0x0~0x7

8

文件名

0x8~0xA

3

扩展名

0xB

1

属性字节

00000000(读写)

00000001(只读)

00000010(隐藏)

00000100(系统)

00001000(卷标)

  00010000(子目录)

00100000(归档)

0xC~0x15

10

系统保留

0x16~0x17

2

文件的最近修改时间

0x18~0x19

2

文件的最近修改日期

0x1A~0x1B

2

表示文件的首簇号

0x1C~0x1F

4

表示文件的长度


    
对表11中的一些取值进行说明:
    (1)
、对于短文件名,系统将文件名分成两部分进行存储,即主文件名+扩展名。0x0~0x7字节记录文件的主文件名,0x8~0xA记录文件的扩展名,取文件名中的ASCII码值。不记录主文件名与扩展名之间的"."  主文件名不足8个字符以空白符(20H)填充,扩展名不足3个字符同样以空白符(20H)填充。0x0偏移处的取值若为00H,表明目录项为空;若为E5H,表明目录项曾被使用,但对应的文件或文件夹已被删除。(这也是误删除后恢复的理论依据)。文件名中的第一个字符若为“.”“..”表示这个簇记录的是一个子目录的目录项。“.”代表当前目录;“..”代表上级目录(和我们在doswindows中的使用意思是一样的,如果磁盘数据被破坏,就可以通过这两个目录项的具体参数推算磁盘的数据区的起始位置,猜测簇的大小等等,故而是比较重要的)
    (2)
0xB的属性字段:可以看作系统将0xB的一个字节分成8位,用其中的一位代表某种属性的有或无。这样,一个字节中的8位每位取不同的值就能反映各个属性的不同取值了。如00000101就表示这是个文件,属性是只读、系统。
    (3)
0xC~0x15在原FAT16的定义中是保留未用的。在高版本的WINDOWS系统中有时也用它来记录修改时间和最近访问时间。那样其字段的意义和FAT32的定义是相同的,见后边FAT32
    (4)
0x16~0x17中的时间=小时*2048+分钟*32+/2。得出的结果换算成16进制填入即可。也就是:0x16字节的0~4位是以2秒为单位的量值;0x16字节的5~7位和0x17字节的0~2位是分钟;0x17字节的3~7位是小时。
    (5)
0x18~0x19中的日期=(年份-1980)*512+月份*32+日。得出的结果换算成16进制填入即可。也就是:0x18字节0~4位是日期数;0x18字节5~7位和0x19字节0位是月份;0x19字节的1~7位为年号,原定义中0~119分别代表1980~2099,目前高版本的Windows允许取0~127,即年号最大可以到2107年。
    (6)
0x1A~0x1B存放文件或目录的表示文件的首簇号,系统根据掌握的首簇号在FAT表中找到入口,然后再跟踪簇链直至簇尾,同时用0x1C~0x1F处字节判定有效性。就可以完全无误的读取文件(目录)了。
    (7)
、普通子目录的寻址过程也是通过其父目录中的目录项来指定的,与数据文件(指非目录文件)不同的是目录项偏移0xB的第4位置1,而数据文件为0

    对于整个FAT分区而言,簇的分配并不完全总是分配干净的。如一个数据区为99个扇区的FAT系统,如果簇的大小设定为2扇区,就会有1个扇区无法分配给任何一个簇。这就是分区的剩余扇区,位于分区的末尾。有的系统用最后一个剩余扇区备份本分区的DBR,这也是一种好的备份方法。
    
早的FAT16系统并没有长文件名一说,Windows操作系统已经完全支持在FAT16上的长文件名了。FAT16的长文件名与FAT32长文件名的定义是相同的,关于长文件名,在FAT32部分再详细作解释


FAT32存储原理:
    FAT32
是个非常有功劳的文件系统,Microsoft成功地设计并运用了它,直到今天NTFS铺天盖地袭来的时候,FAT32依然占据着Microsoft Windows文件系统中重要的地位。FAT32最早是出于FAT16不支持大分区、单位簇容量大以致空间急剧浪费等缺点设计的。实际应用中,FAT32还是成功的。
    FAT32
FAT16的原理基本上是相同的,图4.3.13标出了FAT32分区的基本构成。

4.3.13 Fat32的组织形式

引导扇区

其余保留扇区

FAT1

FAT2(重复的)

根文件夹首簇

其他文件夹及所有文件

剩余扇区

1扇区

31个扇区

实际情况取大小

FAT1

2

 

不足一簇

保留扇区

 

 

┗━━━━━━━━数据区━━━━━━━━┛


    FAT32
在格式化的过程中就根据分区的特点构建好了它的DBR,其中BPB参数是很重要的,可以回过头来看一下表4和表5。首先FAT32保留扇区的数目默认为32个,而不是FAT16的仅仅一个。这样的好处是有助于磁盘DBR指令的长度扩展,而且可以为DBR扇区留有备份空间。上面我们已经提到,构建在FAT32上的win98win2000winXP,其操作系统引导代码并非只占一个扇区了。留有多余的保留扇区就可以很好的拓展OS引导代码。在BPB中也记录了DBR扇区的备份扇区编号。备份扇区可以让我们在磁盘遭到意外破坏时恢复DBR
   
FAT32的文件分配表的数据结构依然和FAT16相同,所不同的是,FAT32将记录簇链的二进制位数扩展到了32位,故而这种文件系统称为FAT3232位二进制位的簇链决定了FAT表最大可以寻址2T个簇。这样即使簇的大小为1扇区,理论上仍然能够寻址1TB范围内的分区。但实际中FAT32是不能寻址这样大的空间的,随着分区空间大小的增加,FAT表的记录数会变得臃肿不堪,严重影响系统的性能。所以在实际中通常不格式化超过32GBFAT32分区。WIN2000及之上的OS已经不直接支持对超过32GB的分区格式化成FAT32,但WIN98依然可以格式化大到127GBFAT32分区,但这样没必要也不推荐。同时FAT32也有小的限制,FAT32卷必须至少有65527个簇,所以对于小的分区,仍然需要使用FAT16FAT12
   
分区变大时,如果簇很小,文件分配表也随之变大。仍然会有上面的效率问题存在。既要有效地读写大文件,又要最大可能的减少空间的浪费。FAT32同样规定了相应的分区空间对应的簇的大小,见表12

 12  FAT32分区大小与对应簇大小

分区空间大小

每个簇的扇区数

簇空间大小(字节)

<8GB

8

4k

>=8GB<16GB

16

8k

>=16GB<32GB

32

16k

>=32GB

64

32k


   
簇的取值意义和FAT16类似,不过是位数长了点罢了,比较见表13

13 FAT各系统记录项的取值含义(16进制)

FAT12记录项的取值

FAT16记录项的取值

FAT32记录项的取值

对应簇的表现情况

000

0000

00000000

未分配的簇

002~FFF

0002~FFEF

00000002~FFFFFFEF

已分配的簇

FF0~FF6

FFF0~FFF6

FFFFFFF0~FFFFFFF6

系统保留

FF7

FFF7

FFFFFFF7

坏簇

FF8~FFF

FFF8~FFFF

FFFFFFF8~FFFFFFFF

0FFFFFF8~0FFFFFFF

文件结束簇

    FAT32的另一项重大改革是根目录的文件化即将根目录等同于普通的文件。这样根目录便没有了FAT16512个目录项的限制,不够用的时候增加簇链,分配空簇即可。而且,根目录的位置也不再硬性地固定了,可以存储在分区内可寻址的任意簇内,不过通常根目录是最早建立的(格式化就生成了)目录表。所以,我们看到的情况基本上都是根目录首簇占簇区顺序上的第1个簇。在图4.3.12中也是按这种情况制作的画的。
   
FAT32对簇的编号依然同FAT16。顺序上第1个簇仍然编号为第2簇,通常为根目录所用(这和FAT16是不同的,FAT16的根目录并不占簇区空间,32个扇区的根目录以后才是簇区第1个簇
    FAT32
的文件寻址方法与FAT16相同,但目录项的各字节参数意义却与FAT16有所不同,一方面它启用了FAT16中的目录项保留字段,同时又完全支持长文件名了。    对于短文件格式的目录项。其参数意义见下表14

14   FAT32短文件目录项32个字节的表示定义

字节偏移(16进制)

字节数

定义

0x0~0x7

8

文件名

0x8~0xA

3

扩展名

0xB*

1

属性字节

00000000(读写)

00000001(只读)

00000010(隐藏)

00000100(系统)

00001000(卷标)

  00010000(子目录)

00100000(归档)

0xC

1

系统保留

0xD

1

创建时间的10毫秒位

0xE~0xF

2

文件创建时间

0x10~0x11

2

文件创建日期

0x12~0x13

2

文件最后访问日期

0x14~0x15

2

文件起始簇号的高16

0x16~0x17

2

文件的最近修改时间

0x18~0x19

2

文件的最近修改日期

0x1A~0x1B

2

文件起始簇号的低16

0x1C~0x1F

4

表示文件的长度

 

      * 此字段在短文件目录项中不可取值0FH,如果设值为0FH,目录段为长文件名目录段


说明:
    (1)
、这是FAT32短文件格式目录项的意义。其中文件名、扩展名、时间、日期的算法和FAT16时相同的。
    (2)
、由于FAT32可寻址的簇号到了32位二进制数。所以系统在记录文件(文件夹)开始簇地址的时候也需要32位来记录,FAT32启用目录项偏移0x14~0x15来表示起始簇号的高16位。
    (3)
、文件长度依然用4个字节表示,这说明FAT32依然只支持小于4GB的文件(目录),超过4GB的文件(目录),系统会截断处理。

    FAT32的一个重要的特点是完全支持长文件名。长文件名依然是记录在目录项中的。为了低版本的OS或程序能正确读取长文件名文件,系统自动为所有长文件名文件创建了一个对应的短文件名,使对应数据既可以用长文件名寻址,也可以用短文件名寻址。不支持长文件名的OS或程序会忽略它认为不合法的长文件名字段,而支持长文件名的OS或程序则会以长文件名为显式项来记录和编辑,并隐藏起短文件名。
   
当创建一个长文件名文件时,系统会自动加上对应的短文件名,其一般有的原则:
    (1)
取长文件名的前6个字符加上"~1"形成短文件名,扩展名不变。
    (2)
如果已存在这个文件名,则符号"~"后的数字递增,直到5
    (3)
如果文件名中"~"后面的数字达到5,则短文件名只使用长文件名的前两个字母。通过数学操纵长文件名的剩余字母生成短文件名的后四个字母,然后加后缀"~1"直到最后(如果有必要,或是其他数字以避免重复的文件名)
    (4)
如果存在老OS或程序无法读取的字符,换以"_"

    长文件名的实现有赖于目录项偏移为0xB的属性字节,当此字节的属性为:只读、隐藏、系统、卷标,即其值为0FH时,DOSWIN32会认为其不合法而忽略其存在。这正是长文件名存在的依据。将目录项的0xB置为0F,其他就任由系统定义了,Windows9xWindows 2000XP通常支持不超过255个字符的长文件名。系统将长文件名以13个字符为单位进行切割,每一组占据一个目录项。所以可能一个文件需要多个目录项,这时长文件名的各个目录项按倒序排列在目录表中,以防与其他文件名混淆。
   
长文件名中的字符采用unicode形式编码(一个巨大的进步哦),每个字符占据2字节的空间。其目录项定义如表15

15   FAT32长文件目录项32个字节的表示定义

字节偏移
(16
进制)

字节数

定义

0x0

1

属性字节位意义

7

保留未用

6

1表示长文件最后一个目录项

5

保留未用

4

顺序号数值

3

2

1

0

0x1~0xA

10

长文件名unicode

0xB

1

长文件名目录项标志,取值0FH

0xC

1

系统保留

0xD

1

校验值(根据短文件名计算得出)

0xE~0x19

12

长文件名unicode

0x1A~0x1B

2

文件起始簇号(目前常置0)

0x1C~0x1F

4

长文件名unicode

注:以上长文件名unicode码一共26个字节,共13个字符
 
  系统在存储长文件名时,总是先按倒序填充长文件名目录项,然后紧跟其对应的短文件名。从表15可以看出,长文件名中并不存储对应文件的文件开始簇、文件大小、各种时间和日期属性。文件的这些属性还是存放在短文件名目录项中,一个长文件名总是和其相应的短文件名一一对应,没有了长文件名还可以用短文件名读,但长文件名如果没有对应的短文件名,不管什么系统都将忽略其存在。所以短文件名是至关重要的。在不支持长文件名的环境中对短文件名中的文件名和扩展名字段作更改(包括删除,因为删除是对首字符改写E5H),都会使长文件名形同虚设。长文件名和短文件名之间的联系光靠他们之间的位置关系维系显然远远不够。其实,长文件名的0xD字节的校验和起很重要的作用,此校验和是用短文件名的11个字符通过一种运算方式来得到的。系统根据相应的算法来确定相应的长文件名和短文件名是否匹配。这个算法不太容易用公式说明,我们用一段c程序来加以说明。
   
假设文件名11个字符组成字符串shortname[],校验和用chknum表示。得到过程如下:

    int ij,chknum=0;
    for (i=11; i>0; i--)
        chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];

 注:  chksum1相与,值为0 0,为1 0x80,然后加上 chksum右移(>>)一位的值,再加上每个字符的代码

    如果通过短文件名计算出来的校验和与长文件名中的0xD偏移处数据不相等。系统无论如何都不会将它们配对的。
   
依据长文件名和短文件名对目录项的定义,加上对簇的编号和链接,FAT32上数据的读取便游刃有余了。

五、实例分析。

1.以下是一幅根目录入口截图:                    11                                               

    从图11上可以看出,0x43000位置的值为0x43,这个数的二制是:第6位为1,表示这是最后一项,第0位和第1位为1,表示3,意为这是第三个目录项。意为第三个目录项是这个长文件名目录项的最后一个项。0x43020的值为02,表示是第二项, 目录项按倒序排列,所以第二项反而在后面;0x43040的值为01,这是第一项;0x43060为短文件名的开始。每个长文件名目录项的0xB位置为0x0F,表示这是长文件名;0xD位置为F9,表示校验码为F90x1A~0x1B位置两个字节常置0

2.以下是U盘分析(FAT16系统)

 a.先看第一个FAT表入口,只有一个文件的时候,就是上图介绍的那个文件(上图是用WIN HEX软件打开的),即整个U盘只有根目录有一个文件wwswwswwswwswwswwswws.txt。此文件大小为9,858字节,此U盘每一个簇只占用一个扇区。看下图:

                                              12

    由图中可以看出,从0x804开始,这个文件从根目录结束后的第一个位置(计数是第2个簇)开始写入文件内容,到0x82B结束,共占用20个簇,一个簇是一个扇区,因此占用20*512=10240字节。图110x4307A~0x4307B两个字节就是文件在数据区的写入位置,也是在FAT表中的位置,在FAT表中,如图120x803之后,0x804~0x805就是第一个簇(编号为第2个簇)的位置,依此类推。0x804~0x805处记录的是0003,也就是连接到第三号簇等等。上图中左边有个“当前所在扇区”是4,就是从DBR区开始,包括DBR区,到这个扇区已过了4个扇区,DBR扇区为第0扇区。也即保留扇区为4个扇区。下图是这个文件的数据区入口:

                                                        13

     U盘根目录区占32个扇区,每个FAT表占250个扇区,所以数据区开始处就是0x43000开始了。自己加一下就知道了。中间经过了250*2+32=532个扇区,加上前FAT表前有4个扇区,所以图中显示“当前所在扇区”为536。下图是这个文件数据区的结束位置。                                  14

      由图14中“当前所在扇区”为555可知,该文件占用555-536+1=20个扇区。但这个扇区没有占满。由图110x4307C~0x4307F是文件大小,即0x00002682,十制的9858字节,从图可以计算出19扇区*512字节+8*16+2=9858字节。

    2.  以上单个文件比较简单,以下介绍在刚才的单文件的基础上创建一个空文件夹。下图为加入空文件夹后根目录截图:

                                             15

      创建文件夹时采用的方法是在空白区使用鼠标右键创建,由图15可以看出,名称为“新建文件”的文件夹已经创建,但是又被删除了,可见在用此法创建文件夹时,只要文件夹中一显示出来即被创建,当我们在文件夹名称处显示编辑时修改文件夹名称时,相当于把这个“新建文件夹”的文件夹删除然后又创建一个按我们改好文件夹名称的文件夹。图中0x3F0800x3F0A0处的E5表示删除。0x3F11A~0x3F11BFAT表入口和数据入口,这个数据所表示的簇的位置又是一个目录表,类似于根目录表,组织数据的方式与根目录完全一样。如下图16

                                            16

以下是空文件夹创建以后FAT表入口图:

                                         17

     从图17中知:空文件夹目录位置在数据区刚才wwswwswwswwswwswwswws.txt文件之后的一个簇,只占一个簇。wwswwswwswwswwswwswws.txt文件结束扇区位置是555,所以如图16,空文件夹的目录位置在第556扇区。如图160x45800处的2E表示该目录项是当前目录的记录,位置在0x4581A~0x4581B0x0016簇的位置,0x45820~0x45821的两个2E表示该目录项是父目录项,0x4583A~0x4583B0x0000表示父目录是根目录。由图16的组织数据的方式知道,FAT16文件夹的组织数据是用文件的方式组织,假定如果文件夹目录记录项用一个簇不够用,则在FAT表中用文件的簇链方法即可。

3.  现在我们要在刚才的空文件夹中COPY入一个文件,看一下是什么变化。如下是根目录入口截图:

                                                18根目录入口截图

    上图与图15完全一样,说明在子目录中对文件删加不影响根目录。现在来看图16的变化:

                                               19文件夹的目录项记录

    由图19可知:这个文件的记录在文件夹的目录项记录中,不在根目录的目录项记录中。图中0x4587A~0x4587B处记录了文件数据开始簇的位置。下面再看一下FAT表的变化:

                                         20   FAT

    由图20可知:这个文件的加入位置也是写在FAT表中的,位置在0x82E~0x82F处开始,此处位置是第17号簇位置,这个文件占用两个簇。这样每个目录的目录项记录都可以用跟文件一样的方式用簇链来表达。比如在0x82C0x82D位置的文件夹,如果这个文件夹内有很多的文件或是文件夹,则有可能在0x82C0x82D位置这个簇就写不下这么多的目录项记录,那么就可以转到一个空的簇继续写,而只是把0x82C0x82D这个位置的值改为新位置的簇号即可,然后在FAT表中同样的新位置写入结尾标志就可以了。可以说明这样一个问题,FAT表中的记录对映着数据区的所有簇。这些簇使用与否都在FAT表中有所记录。目录项记录不管在数据区的哪个地方,所记录的文件或目录的位置都会在FAT表中写入,而FAT表是可以行链式记录的,就连根目录也可以这样,实际上对于根目录,在FAT表的开始位置记录是这样的:F8 FF FF FF,如图20可见,0x804~0x805位置是第0x02号簇,0x802~0x803可不可以看成是0x01号簇呢?当然可以,这个0x01号就是根目录,只是它占用的不是一个簇,而是一个规定大小的范围,如果这个范围不够用也是可以如簇链一样扩展的。0x00号的F8 FF可以看成是开始标志吧。请看下面拷入文件在数据区数据入口图               21

   所在扇区为:557;从图20FAT0x82E~0x82F处可以知道,这个位置是第0x17号簇,从根目录之后中间经过了多少簇呢?计算一下:0x17-0x2=21个簇,根目录入口地址为:0x3F000,所以数据入口地址为:0x3F000+32*512+21*512=0x45A00,所以图上数据入口地址为0x45A00

4.  我们再在刚才COPY入一个文件的文件夹内COPY入一个空文件夹,空文件夹名称为:888888888888888888888888888888,现在来看看截图:                         21   FAT表图()

   图上可见在0x832~0x833处写入了新加入的文件夹目录项入口位置。下面来看根目录有无变化。

                                           22     根目录图(504扇区,见前图)

    由图可见子目录中的变化不会影响根目录,根目录无变化。再看第一重目录(名称为:XXXXXXXXXXXXXXXXXXXXX,位置在第556扇区)的目录项。             23   第一重目录的目录项

    很明显,图中显示了一个新增加的项,0x458EB=0x10表示为文件夹而不是文件。0x458FA~0x458FB记录了FAT表入口位置。我们用前面同样的方法计算出地址为:0x3F000+32*512+23*512=0x45E00(559扇区),如下:

                                                  24

   由图可见,0x45E00处的0x2E表示当前目录的目录项,位置在0x45E1A~0x45E1B处所表示的位置。0x45E20~0x45E21处的0x2E 0x2E表示父目录,0x45E3A~0x45E3B指明了父目录的目录项位置。

5.  现在说一下长文件名跨扇区和跨簇的问题。

       先看四张图                      25    26  27    28

25

26

27

 

 

28

    现在来解释一下上面四个图:先看图25,图25是一张根目录第二扇区的截图,由图可知0x3F3A0开始的目录项,到末尾并未写完,而是接到下一个扇区了(见图26),因为根目录是连续的,所以这种情况说明长文件名记录项是可以跨扇区的;现在再来看一下图27,图27中很明显,由0x45E00可知,这是一个子目录的目录记录项,位置在第0x19簇,这个图结尾部分0x45FA0到结尾是一个长文件名,这个文件名也没有记录完,而是接着写入下一个簇,由位置在第0x19簇,我们看FAT表图(29),如下图:

从上图可知:0x1FC32的位置就是第0x19,这个簇记录的是0x2E,表示下一个簇在第0x2E簇的位置,根目录完已后的地址为0x43000,所以这个0x2E地址在0x43000+(0x2E-0x2)*512=0x48800,由图28可知,这个位置正是0x48800,从图28来看,刚好接上图27。这个就是文件名目录项跨簇。

6.  现在说一下删除的问题。

    删除就是把目录项中的对应记录的每个32字节的第一个字节标为:0xE5,FAT表同位置置0x00,面不是把文件的数据区的内容全部清0,这就是为什么文件删除后,只要不对盘进行任何写操作,就还能找回来的原因。如下图,第一个文件夹内删除一个文件后的FAT表。                30第一个文件内删除一个文件FAT表图

    可见在0x1FC2E~0x1FC31的位置已全部置0,表示这两个簇可以放其它文件了。下面看一下根目录图

                              31   第一个文件内删除一个文件根目录图

   根目录没有任何变化。现在看子目录的目录项图

                                  32 第一个文件内删除一个文件后这个文件夹的目录项图

    由图可见0x458400x45860的地方被标记了0xE5标记,表示该文件被删除。但这个记录项其它内容一点都没有改动,其中就有文件在数据区的起始位置记录,这个起始记录没有破坏,并且还记录有文件长度,所以文件还可以找回一部分来。即可以至少找回一个簇,如果这个文件在存储时是连续簇存储,则可以完全找回,如果不是,则只能找回一个簇的内容,其它簇的内容由于FAT表对应位置清零,就不能找回了。

下面看一下删除文件夹的情况:(这部分内容是后来补上的,所以图号就是以附图x表示)

先见附图1

                         附图1  文件夹88888888888888删除之前FAT

                       附图2  文件夹88888888888888视图(上图)

             附图3  文件夹88888888888888删除之前父目录XXXXXXXXXXXXXXXXXX文件夹的目录表

               附图4  文件夹88888888888888内的一个子目录5kkkk.ghtt的目录表

                              附图5  删除11kkkkkkkkk文件夹后FAT

                              附图6  删除11kkkkkkkkk文件夹后11kkkkkkk的目录表

         说明:上图附图6与没有删除11kkkkkkkkk时完全一样。

                    附图7  删除11kkkkkkkkk文件夹后文件夹888888888888888的目录表

                     附图8  删除888888888888888文件夹后FAT

                  附图9  删除888888888888文件夹后的XXXXXXXXXXXXX文件夹目录表

                      附图10删除888888888888文件夹后的8888888888888888888的目录表

                    附图11删除888888888888文件夹后的8888888888888888888的目录表1

           附图12  删除888888888888文件夹后8888888888之内的一个文件夹6ddddd的目录表

以上删除文件夹的说明:

     1.不管删除文件还是文件夹,也不管该文件夹内是否有子目录,在FAT表中所对应的簇号位置就被清零了,所有子目录所对应的FAT表簇号也被清零,被删除文件夹内所有的文件,不管是在该文件夹内,还是在该文件夹的子目录内,同样FAT表对应簇号也被清零;

     2.被删除的文件夹内的文件,在该文件夹的目录表中记录被打上0xE5标记,所对应的FAT表簇号记录被清零;

     3.被删除的文件夹内的所有子文件夹的在该文件夹的目录表中的所有对应记录项全部打上0xE5标记;

     4.所有子文件夹的目录表所记录的全部记录项,也全部打上0xE5标记,对应的FAT表记录全部清零,所以删除文件夹是要遍历文件夹内所有的子目录和所有的文件,把所有这些内容的记录项打上0xE5标记,对应的FAT表内容清零。

结语:好了,整个FAT16的文件结构全部都比较明晰了,由以上可知,子目录内的文件或是文件夹是必须给出路径,否则就只有用遍历的方法来查找对象。

FAT32

以下来讨论一下FAT32FAT32FAT16变化有一些,但主要精髓没有变,只有簇位置由原来的两个字节表示,变成了四个字节表示,FAT表中用四个字节表示簇位置,因此记录项中启用了FAT16中的保留字,同样构成用四个字节表示;并且FAT32的根目录已不是固定大小了,已经把根目录当成一个文件夹来处理,但位置一般情况下还是在直接接FAT表之后的位置。

                                     33  FAT32格式U盘的DBR图(0扇区)

    上图图33,是用户模式下能够访问的最前的数据了,不能访问MBRDBR之间的扇区.

                                      34 紧接DBR之后的1扇区


                                      
35紧接图34之后的一个扇区

                             36    DBR备份扇区(第6扇区)

                                    37    第一扇区的备份扇区(第7扇区)

                                     38    2扇区的备份扇区(第8扇区)

                                      39    DBR扇区中引导程序的备份(第12扇区)

      以上扇区位置一般固定不变,且备份扇区不能少,如个少了,则不能启动。备份扇区一盘都在第6扇区开始的扇区,顺序备份。第12扇区为DBR扇区中引导程序的备份。

                              40    FAT32格式U盘的FAT

   由图40可见,FAT32的簇位置表示用四个字节,开始标记也由FAT16的二个字节变为四个字节第,第二簇从0x4808开始,结束标记为0x0FFFFFFF

                                           41    FAT32格式U盘的根目录

   由于FAT32格式根目录已经不是固定大小的,而是看成一个文件夹,所以是可扩展的,由图40可见,FAT32格式的数据区就不是FAT16格式样数据区严格在根目录之后,FAT32根目录就已经是数据区,且占第一个簇位置(序号为0x2),而不是数据,根目录不单独存在了。这个根目录占用两个簇,我们看看序号是(0x4)的簇是什么,看下图:

                                42    FAT32格式U盘的根目录之后第一个簇

根目录是从地址0x100000开始的,两个簇之后地址为:0x100000+0x2*0x4*512=0x101000,就是图42中的起始地址,图中可以看出这已经是一个文件夹的目录项记录了,不再是根目录了,如果根目录两个簇都记满了,则可以象其它文件夹目录一样转到其它簇继续记录,用FAT表簇链就可以了。

长文件名的判断

    文件名长短的判断(即什么时候用长文件名)比较复杂,有多种情况,现结合下面几个图来讨论。

                                    43

    43是一个FAT16格式U盘根目录图(XP系统下) 图中列出了几乎是所有文件名的可能情况,其对应的根目录记录项见下:(4个图,从图44~48)

                                           44

                                       45

                                        46

 

 

                                           47

                                             48

       首先说明,这是在WIN XP下的截图,在XP中,MS启用了在文件名目录项中ofs 0xC的字,此字原为保留字。

      1. 当文件名的文件名长度大于8个字节或扩展名大于3个字节,都判为长文件名,这个很正常。写入的时候用长文件名规则写入。

      2.43到图48中特殊文件名的说明见下表:(×表示不使用长文件名使用短文件名表示;√表示使用长文件名表示)

 

序号

文件名

说明    

类型

偏移位置0xC

偏移位置0xB

1

abcdefgh.ijk

8字节+3字节   前后都是小写

文件夹

&H18

×

2

short.txt

短文件名        前后都是小写

文件

&H18

×

3

会员注册.txt

汉字开头

文件

&H00

4

ABAB

全部大写字符  无点

文件夹

&H00

×

5

临时使用

全是汉字      无点

文件夹

&H00

6

ddmm

全部小写字符  无点

文件夹

&H08

×

7

MMdd

前部分大写后部分小写   无点

文件夹

&H00

8

TTMM

全部大写               无点

文件夹

&H00

×

9

66王李

前面为数字或字符后面为汉字  无点

文件夹

&H00

10

dd.dd.mm

有两个点

文件夹

&H00

11

QLL

全为大写字符     无点

文件夹

&H00

×

12

qll

全部小写字符  无点

文件夹

&H08

×

13

一个汉字          无点

文件夹

&H00

14

王大55

前面汉字后面是数字或字符   无点 

文件夹

&H00

15

王伟生

三个汉字        无点 

文件夹

&H00

16

文件ql

前面两个汉字后面字符小写    无点 

文件夹

&H00

17

系统QL

前面两个汉字后面字符大写    无点

文件夹

&H00

18

kjh..ll

全部小写且有两个点挨在一起

文件夹

&H00

19

abcd.TPP

点前面为小写后面为大写

文件夹

&H08

×

20

TUOP.dll

点前面为大写后面为小写

文件夹

&H10

×

21

TYER.GGG

点前面和后面都为大写

文件夹

&H00

×

22

ssed.txT

点前面为小写后面为大小写混写

文件

&H00

23

TURE.txt

点前面为大写后面为小写

文件

&H10

×

24

RARR.TXT

点前面和后面都为大写

文件

&H00

×

25

utxy.TXT

点前面为小写后面为大写

文件

&H08

×

26

dd.txt

点前面汉字字符混合后面小写

文件

&H00

27

DMkr.txt

点前面大小写混合

文件

&H00

28

kk666.TXT

点前小写加数字点后全大写

文件

&H08

×

29

dddff33

全部为小写加数字   无点

文件夹

&H08

×

30

GFGF11

全部为大写加数字   无点

文件夹

&H00

×

31

SD123.txt

点前大写加数字点后全小写

文件

&H10

×

32

ff225.txt

点前小写加数字点后全小写

文件

&H18

×

 

    由图中可知,

       1.只要有汉字,则全部用长文件名表示,不管长度是否超过8个字节;

       2.如果文件名和扩展名全是字符和数字,则只要出现大小写混写,则用长文件名表示;

       3.在短文件名中,只要有两个点的,就用长文件名表示;

       4.在短文件名中,不管是文件还是文件夹,只要没有点,全是小写,则0xC&H08;全是大写,则为&H00,并且使用短文件名表示;

       5.在短文件名中,不管是文件还是文件夹,并且只一个点,如果全是小写,则0xC&H18,并且使用短文件名表示;

       6.在短文件名中,不管是文件还是文件夹,并且只一个点,点前面和点后面哪边为全大写哪边出现1,全部为大写就0xC&H00,并且使用短文件名表示;(如下图)

             8              7           6           5             4           3           2             1

0

0

0

10

10

0

0

0

0xC

 

       5位为“1”,则0xC&H10,表示文件名大写而扩展名小写;第4位为“1”,则0xC&H08,表示文件名大写而扩展名小写;

       7.在有阿拉伯数字和字符混合的短文件名中,先把数字取掉后按以上方法判断即可。

由图中我们还可以得出,文件的大小为0字节时,这个文件的起始簇号是没有标的,到这个文件被写入内容时才标记。

 
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值