📄 fat文件系统原理(四).htm
字号:
size=2>00000001(只读)</FONT></TD></TR>
<TR>
<TD align=middle width=138 height=21><FONT
size=2>00000010(隐藏)</FONT></TD></TR>
<TR>
<TD align=middle width=138 height=21><FONT
size=2>00000100(系统)</FONT></TD></TR>
<TR>
<TD align=middle width=138 height=21><FONT
size=2>00001000(卷标)</FONT></TD></TR>
<TR>
<TD align=middle width=138 height=21><FONT size=2>
00010000(子目录)</FONT></TD></TR>
<TR>
<TD align=middle width=138 height=21><FONT
size=2>00100000(归档)</FONT></TD></TR>
<TR>
<TD align=middle width=123 height=15><FONT
size=2>0xC~0x15</FONT></TD>
<TD align=middle width=86 height=15><FONT
size=2>10</FONT></TD>
<TD align=middle colSpan=2 height=15><FONT
size=2>系统保留</FONT></TD></TR>
<TR>
<TD align=middle width=123 height=15><FONT
size=2>0x16~0x17</FONT></TD>
<TD align=middle width=86 height=15><FONT
size=2>2</FONT></TD>
<TD align=middle colSpan=2 height=15><FONT
size=2>文件的最近修改时间</FONT></TD></TR>
<TR>
<TD align=middle width=123 height=15><FONT
size=2>0x18~0x19</FONT></TD>
<TD align=middle width=86 height=15><FONT
size=2>2</FONT></TD>
<TD align=middle colSpan=2 height=15><FONT
size=2>文件的最近修改日期</FONT></TD></TR>
<TR>
<TD align=middle width=123 height=15><FONT
size=2>0x1A~0x1B</FONT></TD>
<TD align=middle width=86 height=15><FONT
size=2>2</FONT></TD>
<TD align=middle colSpan=2 height=15><FONT
size=2>表示文件的首簇号</FONT></TD></TR>
<TR>
<TD align=middle width=123 height=15><FONT
size=2>0x1C~0x1F</FONT></TD>
<TD align=middle width=86 height=15><FONT
size=2>4</FONT></TD>
<TD align=middle colSpan=2 height=15><FONT
size=2>表示文件的长度</FONT></TD></TR></TBODY></TABLE>
<P><FONT
color=#c0c0c0></FONT> 对图10中的一些取值进行说明:<BR> (1)、对于短文件名,系统将文件名分成两部分进行存储,即主文件名+扩展名。0x0~0x7字节记录文件的主文件名,0x8~0xA记录文件的扩展名,取文件名中的ASCII码值。不记录主文件名与扩展名之间的"."
主文件名不足8个字符以空白符(20H)填充,扩展名不足3个字符同样以空白符(20H)填充。0x0偏移处的取值若为00H,表明目录项为空;若为E5H,表明目录项曾被使用,但对应的文件或文件夹已被删除。(这也是误删除后恢复的理论依据)。文件名中的第一个字符若为“.”或“..”表示这个簇记录的是一个子目录的目录项。“.”代表当前目录;“..”代表上级目录(和我们在dos或windows中的使用意思是一样的,如果磁盘数据被破坏,就可以通过这两个目录项的具体参数推算磁盘的数据区的起始位置,猜测簇的大小等等,故而是比较重要的)<BR> (2)、0xB的属性字段:可以看作系统将0xB的一个字节分成8位,用其中的一位代表某种属性的有或无。这样,一个字节中的8位每位取不同的值就能反映各个属性的不同取值了。如00000101就表示这是个文件,属性是只读、系统。<BR> (3)、0xC~0x15在原FAT16的定义中是保留未用的。在高版本的WINDOWS系统中有时也用它来记录修改时间和最近访问时间。那样其字段的意义和FAT32的定义是相同的,见后边FAT32。<BR> (4)、0x16~0x17中的时间=小时*2048+分钟*32+秒/2。得出的结果换算成16进制填入即可。<SPAN
class=nbody>也就是:0x16字节的0~4位是以2秒为单位的量值;0x16字节的5~7位和0x17字节的0~2位是分钟;0x17字节的3~7位是小时。<BR>
(5)、0x18~0x19中的</SPAN>日期=(年份-1980)*512+月份*32+日。得出的结果换算成16进制填入即可。<SPAN
class=nbody>也就是:0x18字节0~4位是日期数;0x18字节5~7位和0x19字节0位是月份;0x19字节的1~7位为年号,原定义中0~119分别代表1980~2099,目前高版本的Windows允许取0~127,即年号最大可以到2107年。<BR>
(6)、0x1A~0x1B存放文件或目录的表示文件的首簇号,系统根据掌握的首簇号在FAT表中找到入口,然后再跟踪簇链直至簇尾,同时用0x1C~0x1F处字节判定有效性。就可以完全无误的读取文件(目录)了。<BR>
(7)、普通子目录的寻址过程也是通过其父目录中的目录项来指定的,与数据文件(指非目录文件)不同的是目录项偏移0xB的第4位置1,而数据文件为0。</SPAN></P>
<P><SPAN
class=nbody> 对于整个FAT分区而言,簇的分配并不完全总是分配干净的。如一个数据区为99个扇区的FAT系统,如果簇的大小设定为2扇区,就会有1个扇区无法分配给任何一个簇。这就是分区的剩余扇区,位于分区的末尾。有的系统用最后一个剩余扇区备份本分区的DBR,这也是一种好的备份方法。<BR> 早的FAT16系统并没有长文件名一说,Windows操作系统已经完全支持在FAT16上的长文件名了。</SPAN>FAT16的长文件名与FAT32长文件名的定义是相同的,关于长文件名,在FAT32部分再详细作解释<FONT
color=#006699 size=2><I>。</I></FONT></P>
<P>★FAT32存储原理:<BR>
FAT32是个非常有功劳的文件系统,Microsoft成功地设计并运用了它,直到今天NTFS铺天盖地袭来的时候,FAT32依然占据着Microsoft
Windows文件系统中重要的地位。FAT32最早是出于FAT16不支持大分区、单位簇容量大以致空间急剧浪费等缺点设计的。实际应用中,FAT32还是成功的。<BR> FAT32与FAT16的原理基本上是相同的,图4.3.12标出了FAT32分区的基本构成。</P>
<TABLE id=table24 style="WIDTH: 626px; HEIGHT: 85px" width=626
border=0>
<TBODY>
<TR>
<TD align=middle colSpan=7><I><FONT color=#006699
size=2>图4.3.12 Fat32的组织形式</FONT></I></TD></TR>
<TR>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="7%"><FONT color=#006699
size=2>引导扇区</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="10%"><FONT color=#006699
size=2>其余保留扇区</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="15%"><FONT color=#006699
size=2>FAT1</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="16%"><FONT color=#006699
size=2>FAT2(重复的)</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="8%"><FONT color=#006699
size=2>根文件夹首簇</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="30%"><FONT color=#006699
size=2>其他文件夹及所有文件</FONT></TD>
<TD
style="BORDER-RIGHT: #008080 1px solid; BORDER-TOP: #008080 1px solid; BORDER-LEFT: #008080 1px solid; BORDER-BOTTOM: #008080 1px solid; BACKGROUND-COLOR: #c0c0c0"
align=middle width="9%"><FONT color=#006699
size=2>剩余扇区</FONT></TD></TR>
<TR>
<TD align=middle width="7%"><FONT color=#006699
size=2><I>1扇区</I></FONT></TD>
<TD align=middle width="10%"><FONT color=#006699
size=2><I>31个扇区</I></FONT></TD>
<TD align=middle width="15%"><FONT color=#006699
size=2><I>实际情况取大小</I></FONT></TD>
<TD align=middle width="17%"><FONT color=#006699
size=2><I>同FAT1</I></FONT></TD>
<TD align=middle width="8%"><FONT color=#006699
size=2><I>第2簇</I></FONT></TD>
<TD align=middle width="30%"><FONT size=2> </FONT></TD>
<TD align=middle width="9%"><FONT color=#006699
size=2><I>不足一簇</I></FONT></TD></TR>
<TR>
<TD align=middle width="18%" colSpan=2><I><FONT
color=#006699 size=2>保留扇区</FONT></I></TD>
<TD align=middle width="15%"><FONT size=2> </FONT></TD>
<TD align=middle width="17%"><FONT size=2> </FONT></TD>
<TD align=middle width="49%" colSpan=3><FONT
color=#006699
size=2>┗━━━━━━━━<I>数据区</I>━━━━━━━━┛</FONT></TD></TR></TBODY></TABLE>
<P><FONT color=#c0c0c0></FONT>
FAT32在格式化的过程中就根据分区的特点构建好了它的DBR,其中BPB参数是很重要的,可以回过头来看一下表4和表5。首先FAT32保留扇区的数目默认为32个,而不是FAT16的仅仅一个。这样的好处是有助于磁盘DBR指令的长度扩展,而且可以为DBR扇区留有备份空间。上面我们已经提到,构建在FAT32上的win98或win2000、winXP,其操作系统引导代码并非只占一个扇区了。留有多余的保留扇区就可以很好的拓展OS引导代码。在BPB中也记录了DBR扇区的备份扇区编号。备份扇区可以让我们在磁盘遭到意外破坏时恢复DBR。<BR>
FAT32的文件分配表的数据结构依然和FAT16相同,所不同的是,FAT32将记录簇链的二进制位数扩展到了32位,故而这种文件系统称为FAT32。32位二进制位的簇链决定了FAT表最大可以寻址2T个簇。这样即使簇的大小为1扇区,理论上仍然能够寻址1TB范围内的分区。但实际中FAT32是不能寻址这样大的空间的,随着分区空间大小的增加,FAT表的记录数会变得臃肿不堪,严重影响系统的性能。所以在实际中通常不格式化超过32GB的FAT32分区。WIN2000及之上的OS已经不直接支持对超过32GB的分区格式化成FAT32,但WIN98依然可以格式化大到127GB的FAT32分区,但这样没必要也不推荐。同时FAT32也有小的限制,FAT32卷必须至少有65527个簇,所以对于小的分区,仍然需要使用FAT16或FAT12。<BR>
分区变大时,如果簇很小,文件分配表也随之变大。仍然会有上面的效率问题存在。既要有效地读写大文件,又要最大可能的减少空间的浪费。FAT32同样规定了相应的分区空间对应的簇的大小,见表12:</P>
<P> </P>
<TABLE id=table25 style="WIDTH: 421px; HEIGHT: 116px"
width=421 border=1>
<TBODY>
<TR>
<TD align=middle colSpan=3>表12
FAT32分区大小与对因簇大小</TD></TR>
<TR>
<TD align=middle width="26%">分区空间大小</TD>
<TD align=middle width="29%">每个簇的扇区</TD>
<TD align=middle width="18%">簇空间大小</TD></TR>
<TR>
<TD align=middle width="26%"><8GB</TD>
<TD align=middle width="29%">8</TD>
<TD align=middle width="18%">4k</TD></TR>
<TR>
<TD align=middle width="26%">>=8GB且<16GB</TD>
<TD align=middle width="29%">16</TD>
<TD align=middle width="18%">8k</TD></TR>
<TR>
<TD align=middle width="26%">>=16GB且<32GB</TD>
<TD align=middle width="29%">32</TD>
<TD align=middle width="18%">16k</TD></TR>
<TR>
<TD align=middle width="26%">>=32GB</TD>
<TD align=middle width="29%">64</TD>
<TD align=middle width="18%">32k</TD></TR></TBODY></TABLE>
<P><FONT color=#c0c0c0></FONT>
簇的取值意义和FAT16类似,不过是位数长了点罢了,比较见表13:</P>
<TABLE id=table26 style="WIDTH: 405px; HEIGHT: 178px"
width=405 border=1>
<TBODY>
<TR>
<TD align=middle colSpan=4><FONT size=2>表13
FAT各系统记录项的取值含义(16进制)</FONT></TD></TR>
<TR>
<TD align=middle width="16%"><FONT
size=2>FAT12记录项的取值</FONT></TD>
<TD align=middle width="22%"><FONT
size=2>FAT16记录项的取值</FONT></TD>
<TD align=middle width="27%"><FONT
size=2>FAT32记录项的取值</FONT></TD>
<TD align=middle width="18%"><FONT
size=2>对应簇的表现情况</FONT></TD></TR>
<TR>
<TD align=middle width="16%">000</TD>
<TD align=middle width="22%"><FONT size=2>0000</FONT></TD>
<TD align=middle width="27%"><FONT
size=2>00000000</FONT></TD>
<TD align=middle width="18%"><FONT
size=2>未分配的簇</FONT></TD></TR>
<TR>
<TD align=middle width="16%"><FONT
size=2>002~FFF</FONT></TD>
<TD align=middle width="22%"><FONT
size=2>0002~FFEF</FONT></TD>
<TD align=middle width="27%"><FONT
size=2>00000002~FFFFFFEF</FONT></TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -