如何從檔案系統中讀取檔案內容
阿新 • • 發佈:2019-01-01
【0】寫在前面
0.0) text description from orange’s implemention of a os ,文末總結繫個人臆測出的乾貨
【1】intro to FAT12(file allocation table 12)檔案系統格式(from Baidu Baike)
- (1)FAT12定義: FAT12是DOS時代就開始使用的檔案系統(File System),直到2009年仍然在軟盤上使用。
- (2)FAT12的主磁碟結構:
- 2.1)引導扇區(Boot Sector):位於第一個扇區,在軟盤上就是0柱面(磁軌)0磁頭1扇區。
- 2.2)檔案分配表(FAT):緊接著引導扇區的是兩個完全相同的FAT表,每個FAT表佔用9個(FAT2是FAT1 的 copy)
- 2.3)根目錄區: FAT表之後是根目錄區,根目錄區長度不固定
- 2.4)資料區:根目錄後面就是資料區
【2.1】FAT12的引導扇區格式:
名稱 開始位元組 長度 內容 參考值 BS_jmpBOOT 0 3 一個短跳轉指令 jmp Label_07c00H nop BS_OEMName 3 8 廠商名 'QingFeng' BPB_BytesPerSec 11 2 每扇區位元組數(Bytes/Sector) 0x200 BPB_SecPerClus 13 1 每簇扇區數(Sector/Cluster) 0x1 BPB_ResvdSecCnt 14 2 Boot記錄佔用多少扇區 ox1 BPB_NumFATs 16 1 共有多少FAT表 0x2 BPB_RootEntCnt 17 2 根目錄區檔案最大數 0xE0 BPB_TotSec16 19 2 扇區總數 0xB40[2*80*18] BPB_Media 21 1 介質描述符 0xF0 BPB_FATSz16 22 2 每個FAT表所佔扇區數 0x9 BPB_SecPerTrk 24 2 每磁軌扇區數(Sector/track) 0x12 BPB_NumHeads 26 2 磁頭數(面數) 0x2 BPB_HiddSec 28 4 隱藏扇區數 0 BPB_TotSec32 32 4 如果BPB_TotSec16=0,則由這裡給出扇區數 0 BS_DrvNum 36 1 INT 13H的驅動器號 0 BS_Reserved1 37 1 保留,未使用 0 BS_BootSig 38 1 擴充套件引導標記(29h) 0x29 BS_VolID 39 4 卷序列號 0 BS_VolLab 43 11 卷標 'QingFeng' BS_FileSysType 54 8 檔案系統型別 'FAT12' 引導程式碼及其他內容 62 448 引導程式碼及其他資料 引導程式碼(剩餘空間用0填充) 結束標誌0xAA55 510 2 第510位元組為0x55,第511位元組為0xAA 0xAA55
【2.2】檔案分配表-FAT
- a)FAT的作用:當檔案size 大於 512B,則FAT是找出該檔案所佔用的簇(簇:一個或多個扇區,引導扇區的BPB_SecPerClus記錄該數字)
- b)FAT項:每個項佔用12 位,代表一個簇,第0和1個簇不使用,從第2個FAT項 開始表示資料區的每一個簇,即是第2個FAT項表示資料區第一個簇。資料區的第一個簇號是2,和這裡是呼應的 。(注意: FAT項值代表的是檔案的下一個簇號)
看個荔枝(只看16個位元組):(乾貨)
如FAT所在扇區(一個扇區512位元組)儲存值為:F0 FF FF FF 8F 00 FF FF FF FF FF FF 09 A0 00 FF , 0F 00 00 ; 則簇號分別為:0-FF0 1-FFF 2-FFF 3-008 4-FFF 5-FFF 6-FFF 7-FFF 8-009 9-00A A-FFF
如果根目錄去中有條目記載某檔案A 的 DIR_FstClus=3的話,則對應第3個FAT項,結合上一行,我們知道FAT3==008,所以下一個簇號是8-009 , 以此類推9-00A、 A-FFF。FFF就表示這個簇是最後一個簇了。
【2.3】根目錄區-root dir sector
- a)根目錄區中的每一個條目佔用32位元組,每個條目格式如下:
- b)根目錄區的大小依賴於 BPB_RootEntCnt(引導扇區中的BPB_RootEntCnt,根目錄區檔案最大數==根目錄條目數),所以長度不固定;
如何計算根目錄區的扇區數量?
顯然,BPB_RootEntCnt 和 BPB_BytePerSec 都是由軟盤(檔案系統FAT12所在的分割槽)的引導扇區提供的;
所以,我們可以算出該軟盤的根目錄扇區數量。
【2.4】資料區
- a)資料區的第一個簇的簇號是2,而不是0 or 1;
【3】下面,我們講一下,如何從檔案系統中讀取一個檔案的內容(讀取某檔案的步驟)(純屬個人臆測,乾貨):
- a)應用程式給出檔名;
- b)通過該分割槽(檔案系統)的引導扇區算出 根目錄目錄 所佔扇區大小 和 資料區的起始扇區;
- c)依據app 給出的檔名 和 根目錄項的DIR_Name 定位該檔名對應的根目錄項(根目錄條目);
- d)該條目記錄了 對應檔案的起始簇號,並將 該簇號 送到 FAT1 以找出該檔案的佔用的所有簇號;(FAT2 是 FAT1 的copy)
- e)拿到該檔案的所有簇號後,依據步驟a)算出的資料區起始扇區,從資料區中 取出 這些簇號裡的內容,至此,取出該檔案的內容;