1、題外話
在繼續本文學習FAT32文件系統之前,先來插入一點別的話題。我們都知道U盤有一個屬性是容量,就拿筆者的U盤為例,筆者手上的U盤是金士頓的DataTraveler G3 4GB的一個U盤。電腦上顯示的容量如圖1所示為3.75GB。那么這個3.75GB是怎么計算出來的呢?

我們先來回顧一下上一篇BPB參數當中的Sectors(扇區總數)這個參數,這一參數代表了這個U盤在出廠時的總扇區數,筆者手上這個是7884672個,可以從圖2中看到。其中每個扇區為512 B,也就是說總共可以容納4036952064 B 約為 3.76GB 的數據。但是這其中一部分是要用來存放FAT32文件系統的相關信息參數的,比如FAT表,BPB等。我們這邊來算一下,首先需要減去1016個保留扇區,還有兩個FAT表總共是7684 * 2 = 15368個扇區,所示還剩下的字節數為4036952064 B - ( 1016 + 15368 ) * 512 B = 4028563456 B 正好是圖中顯示的容量。所以可以得出結論,系統顯示的U盤容量 = ( 總扇區數 - 保留扇區數 - FAT表扇區數 * FAT表個數 ) * 512 B。經計算可得實際的使用率是99.79%。所以相對與整個U盤來說,FAT32文件系統用於存儲相關信息部分的損耗是很小的。

好了,接下來進入正題,繼續學習FAT32文件系統的FAT表部分。
2、本文目錄
3、FAT表的讀取
首先FAT表一般來說有兩張,另一張用於備份。兩張表是前后緊挨在一起的,只要計算出了FAT1表的偏移之后加上FAT表的大小就可以得到FAT2表的偏移。FAT1表的偏移地址計算公式如下[4] :
FAT1表偏移 = 保留扇區數 * 每扇區字節數
由圖2可知,在本例中,FAT1表的偏移 = 1016 * 512 B = 520192 = 0x7F000。同理:
FAT2表的偏移 = FAT1+FAT表的大小 = (保留扇區數 + FAT表扇區數) * 每扇區字節數
在本例中,FAT2表的偏移 = (1016 + 7684) * 512 B = 4454400 = 0x43F800。用上一篇中講到的程序可以讀取出兩張FAT表的內容,一般情況下兩張表的內容應該是完全一樣的。筆者讀取了第一張FAT表起始部分的內容,如圖3所示:

4、FAT表項
在分析FAT表之前先來說明一下FAT的構成。FAT表即文件分配表(File Allocation Table)。FAT32文件表是由一個個表項組成的一張表,其中每一個表項由一個32位的二進制組成,其值對應了相應簇的使用情況,如2號表項對應了2號簇的使用情況,3號表項對應了3號簇的使用情況,依此類推。(但是第0和第1項例外,下面會有說明)。每個表項對應數值的含義如表1所示[2]:
| 表項數值 | 對應含義 |
| 0x00000000 | 空閑簇,即表示可用 |
| 0x00000001 | 保留簇 |
| 0x00000002 - 0x0FFFFFEF | 被占用的簇,其值指向下一個簇號 |
| 0x0FFFFFF0 - 0x0FFFFFF6 | 保留值 |
| 0x0FFFFFF7 | 壞簇 |
| 0x0FFFFFF8 - 0x0FFFFFFF | 文件最后一個簇 |
具體每一項填寫的內容規則如下表所示:如果該簇是文件的最后一簇,填入的值為0x0FFFFFFF;如果該簇不是文件的最后一簇,則填入的值為該文件占用的下一簇號(所以我們可以看到在FAT32中文件是以簇鏈的形式保存起來的)。下面我們根據實際情況,圖3來分析一下FAT表的含義。
FAT表第0項(0x00000000~0x00000003): 0x0FFFFF8
FAT表第1項(0x00000004~0x00000007): 0xFFFFFFFF
這兩項不代表任何簇的使用情況,而是FAT表的表頭,表征了介質描述,是固定值,所以0x00和0x01這兩個簇號是不用的,簇號的下標從2開始。其中1號表項可能被用於記錄臟標志,以說明文件系統沒有被正常卸載或者磁盤表面存在錯誤。接下來
FAT表第2項(0x00000008~0x0000000B): 0x0FFFFFFF
第2項存儲的是第2簇的使用情況,通常第2簇存儲的是文件系統的根目錄。雖然在FAT32文件系統中,根目錄的位置不再硬性地固定,可以存儲在分區內可尋址的任意簇內,不過通常根目錄是最早建立的(格式化就生成了)目錄表。所以,我們看到的情況基本上都是根目錄首簇緊鄰FAT2,占簇區順序上的第1個簇(即2號簇)。同時,FAT32文件系統將根目錄當做普通的數據文件來看,所有沒有了目錄項數的限制,在需要的時候可以分配空簇,存儲更多的目錄項[1]。
這一項的值為0x0FFFFFFF ,說明根目錄占用且只占用了1個簇。
FAT表第3 ……
這里再穿插一點題外話,FAT32格式文件分配的最小單位是簇。也就是說你存儲了一個實際大小1kB的文件,那么它占用的存儲空間還是1簇(在這里換算成大小即為8*512B = 4KB)。筆者以一個實際的例子來說明一下:在U盤中放入一個8B大小的temp.txt文件,然后查看文件屬性的時候發現其占用空間是4KB,和我們上面講的理論符合。

圖 4 temp.txt的大小和占用空間
看了下篇幅也差不多了,那么本文關於FAT表的部分到此結束。其實本來也沒多少內容,筆者想到哪就扯到哪,胡扯了些其他的東西。剩下的數據區部分就留到下一篇當中再講好了。同樣的,本文當中有一些內容是筆者自己思考理解甚至推測出來的,如果有錯誤的地方歡迎指正,以免誤人子弟了(笑)。
5、參考文獻
1、FAT32文件系統的存儲組織結構(一) http://blog.chinaunix.net/uid-26913704-id-3213948.html
2、FAT32 http://baike.baidu.com/view/45233.htm?fr=aladdin
3、基於U盤FAT32文件系統的分析 http://wenku.baidu.com/link?url=cIKgrwV66y4CoyuOEB1-OhjRY9tnXtIAoZuYEwDCjxbyRomSIiJgBAXGxq6LudfwuopUpYhiVd8TjxrBFoVyPs0NX3OqbnoWjyn4ZAx60Wi
4、FAT 32 文件格式 http://blog.csdn.net/shrekmu/article/details/5950414
