1. 程式人生 > >如何從檔案系統中讀取檔案內容

如何從檔案系統中讀取檔案內容

【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)算出的資料區起始扇區,從資料區中 取出 這些簇號裡的內容,至此,取出該檔案的內容;