本文來自網(wǎng)絡(luò)整理。
FAT32是個非常有功勞的文件系統(tǒng),Microsoft成功地設(shè)計并運用了它,直到今天NTFS鋪天蓋地襲來的時候,F(xiàn)AT32依然占據(jù)著Microsoft Windows文件系統(tǒng)中重要的地位。FAT32最早是出于FAT16不支持大分區(qū)、單位簇容量大以致空間急劇浪費等缺點設(shè)計的。實際應(yīng)用中,F(xiàn)AT32還是成功的。
FAT32與FAT16的原理基本上是相同的,下圖標出了FAT32分區(qū)的基本構(gòu)成。
FAT32分區(qū)的基本構(gòu)成
FAT32在格式化的過程中就根據(jù)分區(qū)的特點構(gòu)建好了它的DBR,其中BPB參數(shù)是很重要的,可以回過頭來看一下表4和表5。首先FAT32保留扇區(qū)的數(shù)目默認為32個,而不是FAT16的僅僅一個。這樣的好處是有助于磁盤DBR指令的長度擴展,而且可以為DBR扇區(qū)留有備份空間。上面我們已經(jīng)提到,構(gòu)建在FAT32上的win98或win2000、winXP,其操作系統(tǒng)引導(dǎo)代碼并非只占一個扇區(qū)了。留有多余的保留扇區(qū)就可以很好的拓展OS引導(dǎo)代碼。在BPB中也記錄了DBR扇區(qū)的備份扇區(qū)編號。備份扇區(qū)可以讓我們在磁盤遭到意外破壞時恢復(fù)DBR。
FAT32的文件分配表的數(shù)據(jù)結(jié)構(gòu)依然和FAT16相同,所不同的是,F(xiàn)AT32將記錄簇鏈的二進制位數(shù)擴展到了32位,故而這種文件系統(tǒng)稱為FAT32。32位二進制位的簇鏈決定了FAT表最大可以尋址2T個簇。這樣即使簇的大小為1扇區(qū),理論上仍然能夠?qū)ぶ?TB范圍內(nèi)的分區(qū)。但實際中FAT32是不能尋址這樣大的空間的,隨著分區(qū)空間大小的增加,F(xiàn)AT表的記錄數(shù)會變得臃腫不堪,嚴重影響系統(tǒng)的性能。所以在實際中通常不格式化超過32GB的FAT32分區(qū)。WIN2000及之上的OS已經(jīng)不直接支持對超過32GB的分區(qū)格式化成FAT32,但WIN98依然可以格式化大到127GB的FAT32分區(qū),但這樣沒必要也不推薦。同時FAT32也有小的限制,F(xiàn)AT32卷必須至少有65527個簇,所以對于小的分區(qū),仍然需要使用FAT16或FAT12。
分區(qū)變大時,如果簇很小,文件分配表也隨之變大。仍然會有上面的效率問題存在。既要有效地讀寫大文件,又要最大可能的減少空間的浪費。FAT32同樣規(guī)定了相應(yīng)的分區(qū)空間對應(yīng)的簇的大小,見下表:
FAT32分區(qū)大小及對應(yīng)的簇的大小
FAT32簇的取值意義和FAT16類似,不過是位數(shù)長了點罷了,比較見下表:
FAT32簇的取值意義
FAT32的另一項重大改革是根目錄的文件化,即將根目錄等同于普通的文件。這樣根目錄便沒有了FAT16中512個目錄項的限制,不夠用的時候增加簇鏈,分配空簇即可。而且,根目錄的位置也不再硬性地固定了,可以存儲在分區(qū)內(nèi)可尋址的任意簇內(nèi),不過通常根目錄是最早建立的(格式化就生成了)目錄表。所以,我們看到的情況基本上都是根目錄首簇占簇區(qū)順序上的第1個簇。
FAT32對簇的編號依然同F(xiàn)AT16。順序上第1個簇仍然編號為第2簇,通常為根目錄所用(這和FAT16是不同的,F(xiàn)AT16的根目錄并不占簇區(qū)空間,32個扇區(qū)的根目錄以后才是簇區(qū)第1個簇)
FAT32的文件尋址方法與FAT16相同,但目錄項的各字節(jié)參數(shù)意義卻與FAT16有所不同,一方面它啟用了FAT16中的目錄項保留字段,同時又完全支持長文件名了。
對于短文件格式的目錄項。其參數(shù)意義見下表:
FAT32短文件目錄項32個字節(jié)的表示定義
說明:
(1)、這是FAT32短文件格式目錄項的意義。其中文件名、擴展名、時間、日期的算法和FAT16時相同的。
(2)、由于FAT32可尋址的簇號到了32位二進制數(shù)。所以系統(tǒng)在記錄文件(文件夾)開始簇地址的時候也需要32位來記錄,F(xiàn)AT32啟用目錄項偏移0x12~0x13來表示起始簇號的高16位。
(3)、文件長度依然用4個字節(jié)表示,這說明FAT32依然只支持小于4GB的文件(目錄),超過4GB的文件(目錄),系統(tǒng)會截斷處理。
FAT32的一個重要的特點是完全支持長文件名。長文件名依然是記錄在目錄項中的。為了低版本的OS或程序能正確讀取長文件名文件,系統(tǒng)自動為所有長文件名文件創(chuàng)建了一個對應(yīng)的短文件名,使對應(yīng)數(shù)據(jù)既可以用長文件名尋址,也可以用短文件名尋址。不支持長文件名的OS或程序會忽略它認為不合法的長文件名字段,而支持長文件名的OS或程序則會以長文件名為顯式項來記錄和編輯,并隱藏起短文件名。
當(dāng)創(chuàng)建一個長文件名文件時,系統(tǒng)會自動加上對應(yīng)的短文件名,其一般有的原則:
(1)、取長文件名的前6個字符加上"~1"形成短文件名,擴展名不變。
(2)、如果已存在這個文件名,則符號"~"后的數(shù)字遞增,直到5。
(3)、如果文件名中"~"后面的數(shù)字達到5,則短文件名只使用長文件名的前兩個字母。通過數(shù)學(xué)操縱長文件名的剩余字母生成短文件名的后四個字母,然后加后綴"~1"直到最后(如果有必要,或是其他數(shù)字以避免重復(fù)的文件名)。
(4)、如果存在老OS或程序無法讀取的字符,換以"_"
長文件名的實現(xiàn)有賴于目錄項偏移為0xB的屬性字節(jié),當(dāng)此字節(jié)的屬性為:只讀、隱藏、系統(tǒng)、卷標,即其值為0FH時,DOS和WIN32會認為其不合法而忽略其存在。這正是長文件名存在的依據(jù)。將目錄項的0xB置為0F,其他就任由系統(tǒng)定義了,Windows9x或Windows 2000、XP通常支持不超過255個字符的長文件名。系統(tǒng)將長文件名以13個字符為單位進行切割,每一組占據(jù)一個目錄項。所以可能一個文件需要多個目錄項,這時長文件名的各個目錄項按倒序排列在目錄表中,以防與其他文件名混淆。
長文件名中的字符采用unicode形式編碼(一個巨大的進步哦),每個字符占據(jù)2字節(jié)的空間。其目錄項定義如下表。
FAT32長文件目錄項32個字節(jié)的表示定義
系統(tǒng)在存儲長文件名時,總是先按倒序填充長文件名目錄項,然后緊跟其對應(yīng)的短文件名。從表15可以看出,長文件名中并不存儲對應(yīng)文件的文件開始簇、文件大小、各種時間和日期屬性。文件的這些屬性還是存放在短文件名目錄項中,一個長文件名總是和其相應(yīng)的短文件名一一對應(yīng),短文件名沒有了長文件名還可以讀,但長文件名如果沒有對應(yīng)的短文件名,不管什么系統(tǒng)都將忽略其存在。所以短文件名是至關(guān)重要的。在不支持長文件名的環(huán)境中對短文件名中的文件名和擴展名字段作更改(包括刪除,因為刪除是對首字符改寫E5H),都會使長文件名形同虛設(shè)。長文件名和短文件名之間的聯(lián)系光靠他們之間的位置關(guān)系維系顯然遠遠不夠。其實,長文件名的0xD字節(jié)的校驗和起很重要的作用,此校驗和是用短文件名的11個字符通過一種運算方式來得到的。系統(tǒng)根據(jù)相應(yīng)的算法來確定相應(yīng)的長文件名和短文件名是否匹配。這個算法不太容易用公式說明,我們用一段c程序來加以說明。
假設(shè)文件名11個字符組成字符串shortname[],校驗和用chknum表示。得到過程如下:
int i,j,chknum=0;
for (i=11; i>0; i--)
chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];
如果通過短文件名計算出來的校驗和與長文件名中的0xD偏移處數(shù)據(jù)不相等。系統(tǒng)無論如何都不會將它們配對的。
依據(jù)長文件名和短文件名對目錄項的定義,加上對簇的編號和鏈接,F(xiàn)AT32上數(shù)據(jù)的讀取便游刃有余了。