FAT16存儲原理: 當把一部分磁盤空間格式化為fat文件系統時,fat文件系統就將這個分區當成整塊可分配的區域進行規劃,以便于數據的存儲。一般來講,其劃分形式如圖7所示。我們把FAT16部分提取出來,詳細描述一下:
FAT16是Microsoft較早推出的文件系統,具有高度兼容性,目前仍然廣泛應用于個人電腦尤其是移動存儲設備中,FAT16簡單來講由圖$2所示的6部分組成(主要是前5部分)。引導扇區(DBR)我們已經說過,FAT16在DBR之后沒有留有任何保留扇區,其后緊隨的便是FAT表。FAT表是FAT16用來記錄磁盤數據區簇鏈結構的。像前面我們說過的例子一樣,FAT將磁盤空間按一定數目的扇區為單位進行劃分,這樣的單位稱為簇。通常情況下,每扇區512字節的原則是不變的。簇的大小一般是2n (n為整數)個扇區的大小,像512B,1K,2K,4K,8K,16K,32K,64K。實際中通常不超過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位的FAT,FAT12是FAT的初始實現形式,是針對小型介質的。FAT12文件分配表要比FAT16和FAT32的文件分配表小,因為它對每個條目使用的空間較少。這就給數據留下較多的空間。所有用FAT12格式化的5.25英寸軟盤以及1.44MB的3.5英寸軟盤都是由FAT12格式化的。除了FAT表中記錄每簇鏈結的二進制位數與FAT16不同外,其余原理與FAT16均相同,不再單獨解釋。。。 格式化FAT16分區時,格式化程序根據分區的大小確定簇的大小,然后根據保留扇區的數目、根目錄的扇區數目、數據區可分的簇數與FAT表本身所占空間 來確定FAT表所需的扇區數目,然后將計算后的結果寫入DBR的相關位置。
(FAT16 DBR參數的偏移0x11和0x12,內容:00 02。轉換一下,就是0200H,表示根目錄項數(Root Entries) 能夠保存在該分區的根目錄文件夾中的32個字節長的文件和文件夾名稱項的總數。在一個典型的硬盤上,本字段的值為512,一般根目錄的扇區數為32個扇區))。偏移0x16和0x17記錄了FAT1一個表所占扇區的數據。偏移0x10記錄了FAT表的副本數目。系統在得到這幾項參數以后,就可以確定數據區的開始扇區偏移了。
FAT16文件系統從根目錄所占的32個扇區之后的第一個扇區開始以簇為單位進行數據的處理,這之前仍以扇區為單位。對于根目錄之后的第一個簇,系統并不編號為第0簇或第1簇 (可能是留作關鍵字的原因吧),而是編號為第2簇,也就是說數據區順序上的第1個簇也是編號上的第2簇。
FAT文件系統之所以有12,16,32不同的版本之分,其根本在于FAT表用來記錄任意一簇鏈接的二進制位數。以FAT16為例,每一簇在FAT表中占據2字節(二進制16位)。所以,FAT16最大可以表示的簇號為0xFFFF(十進制的65535),以32K為簇的大小的話,FAT32可以管理的最大磁盤空間為:32KB×65535=2048MB,這就是為什么FAT16不支持超過2GB分區的原因。
FAT表實際上是一個數據表,以2個字節為單位,我們暫將這個單位稱為FAT記錄項,通常情況其第1、2個記錄項(前4個字節)用作介質描述。從第三個記錄項開始記錄除根目錄外的其他文件及文件夾的簇鏈情況。根據簇的表現情況FAT用相應的取值來描述,見表10 表10 FAT16記錄項的取值含義(16進制)
| FAT16記錄項的取值
| 對應簇的表現情況
| 0000
| 未分配的簇
| 0002~FFEF
| 已分配的簇
| FFF0~FFF6
| 系統保留
| FFF7
| 壞簇
| FFF8~FFFF
| 文件結束簇 一般為FFFF
|
文件的結束符為0D0A。
看一幅在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表創建了一份備份,就是我們看到的FAT2。FAT2與FAT1的內容通常是即時同步的,也就是說如果通過正常的系統讀寫對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,表明目錄項曾被使用,但對應的文件或文件夾已被刪除。(這也是誤刪除后恢復的理論依據)。文件名中的第一個字符若為“.”或“..”表示這個簇記錄的是一個子目錄的目錄項。“.”代表當前目錄;“..”代表上級目錄(和我們在dos或windows中的使用意思是一樣的,如果磁盤數據被破壞,就可以通過這兩個目錄項的具體參數推算磁盤的數據區的起始位置,猜測簇的大小等等,故而是比較重要的)
(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部分再詳細作解釋。
|