《Unix/Linux系統程式設計》第七章學習筆記
第七章 檔案操作
7.1 檔案操作級別
- 硬體級別
fdisk | 將硬碟、u盤或sdc盤區分 |
---|---|
mkfs | 格式化磁碟區分,為系統做好準備 |
fsck | 檢查和維修系統 |
碎片整理 | 壓縮檔案系統中的檔案 |
- 系統呼叫:使用者模式程式使用系統呼叫來訪問核心函式。
- I/O庫函式:系統呼叫可讓使用者讀/寫多個數據塊。
FILE mode I/O: fopen(), fread(), fwrite(), fseek(), fclose(),fflush() char mode I/o: gete(), getchar(), ugetc(), putc(), putchar() line mode I/O: gets(), fgets(), putc(), puts(), fputs() formatted I/O: scanf(), fscanf(), sscanf(), printf(), fprintf(), sprintf()
- 使用者命令:使用者可以使用Unix/Linux命令來執行檔案操作,而不是編寫程式。
kumount(),kumount() (mount/umount file systems) kmkdir(),krmdir() (make/remove directory) kchair(),kgetCwd() (change directory,get CWD pathname) klink(),kunlink() (hard link/unlink files) kchmod(),kchown(),kutime() (change r|w|x permissions,owner,time) kcreat(),kopen() (create/open file for R,W,RW,APPEND) kread(),kwrite() (read/write opened files) klseek(),kclose() (Lseek/close file descriptors) keymlink(),kreadlink () (create/read symbolic 1ink files) kstat(),kfstat(),klatat() (get file status/information) kopendir(),kreaddir() (open/read directories)
7.2 檔案I/O操作
如圖為檔案操作示意圖
分為使用者模式和核心模式操作
-
使用者模式
使用者模式下的程式執行操作
FILE *p = fopen("file", "r"); or FILE *p = fopen( "file", "w");
可以開啟一個讀/寫檔案流。
fopen()在使用者(heap)空間中建立一個FILE結構體,包含一個檔案描述符fd、一個fbuf[BLKSIZE]和一些控制變數。它會向核心中的kopen()發出一個fd = open("file",flags=READ or WRITE)系統呼叫,構建一個OpenTable來表示開啟檔案示例。OpenTable的mptr指向記憶體中的檔案INODE。對於非特殊檔案,INODE 的i_block陣列指向儲存裝置上的資料塊。成功後,fp會指向FILE結構體,其中fd是open()系統呼叫返回的檔案描述符。
fread(ubuf, size,nitem, fp):將nitem個size位元組讀取到ubuf上,通過:
將資料從FILE結構體的fbuf上覆制到ubuf上,若資料足夠、則返回。
如果fbuf沒有更多資料,則執行(a)。
(a)發出read(fd, fbuf, BLKSIZE)系統呼叫,將檔案資料塊從核心讀取到fbuf上,然後將資料複製到ubuf上,直到資料足夠或者檔案無更多資料可複製。
(b)fwrite(ubuf, size, nitem, fp):將資料從ubuf複製到 fbuf。
若(fbuf有空間):將資料複製到fbuf上,並返回。
若(fbuf已滿):發出 write(fd, fbuf, BLKSIZE)系統呼叫,將資料塊寫入核心,然後再次寫入fbuf。
這樣,fread()/fwrite()會向核心發出read(/write)系統呼叫,但僅在必要時發出,而且它們會以塊集大小來傳輸資料,提高效率。同樣,其他庫I/O函式,如 fgetc/fputc、fgets/fputs、fscanf/fprintf等也可以在使用者空間內的FILE結構體中對fbuf進行操作。 -
核心模式
核心中的檔案系統函式:
假設非特殊檔案的read(fd, fbuf[], BLKSIZE)系統呼叫。
在read()系統呼叫中,fd是一個開啟的檔案描述符,它是執行程序的fd陣列中的一個索引,指向一個表示開啟檔案的 OpenTable。
OpenTable包含檔案的開啟模式、一個指向記憶體中檔案 INODE的指標和讀/寫檔案的當前位元組偏移量。從OpenTable的偏移量,
計算邏輯塊編號lbk。
通過 INODE.i_block[]陣列將邏輯塊編號轉換為物理塊編號blk 。
Minode包含檔案的記憶體INODE。EMODE.i_block[]陣列包含指向物理磁碟塊的指標。檔案系統可使用物理塊編號從磁碟塊直接讀取資料或將資料直接寫入磁碟塊,但將會導致過多的物理磁碟I/O。
為提高磁碟VO效率,作業系統核心通常會使用一組I/O緩衝區作為快取記憶體,以減少物理I/O的數量。
7.3 低級別檔案操作
1.分割槽
(1) 主引導記錄(MBR)
一個塊儲存裝置,如硬碟、U盤、SD卡等,可以分為幾個邏輯單元,稱為分割槽。各分割槽均可以格式化為特定的檔案系統,也可以安裝在不同的作業系統上。
(2)格式化分割槽
fdisk只是將一個儲存裝置劃分為多個分割槽。每個分割槽都有特定的檔案系統型別,但是分割槽還不能使用。為了儲存檔案,必須先為特定的檔案系統準備好分割槽。該操作習慣上稱為格式化磁碟或磁碟分割槽。在Linux中,它被稱為mkfs,表示Make檔案系統。Linux支援多種不同型別的檔案系統。
7.4 ET2檔案系統簡介
Block#0:
引導塊,檔案系統不會使用它。它用於容納從磁碟引導作業系統的載入程式。
Block#1:
超級塊(在硬碟分割槽中位元組偏移量為1024)。用於容納關於整個檔案系統的資訊。
Block#2:
塊組描述符(硬碟上的s_first_data_blocks-1)EXT2將磁碟塊分成幾個組,每個組有8192個塊(硬碟上的大小為32K)
Block #8:塊點陣圖(Bmap)
用來表示某種項的位序列。0表示對應項處於FREE狀態,1表示處於IN_USE狀態。1個軟盤有1440個塊,但Block#0未被檔案系統使用,所以對應點陣圖只有1439個有效位,無效位視作IN_USE處理,設定為1.
Block #9:索引節點點陣圖(Imap)
一個索引節點就是用來代表一個檔案的資料結構。EXT2檔案系統是使用有限數量的索引節點建立的。各索引節點的狀態用B9 中 Imap中的一個位表示。在EXT2 FS 中,前10個索引節點是預留的。所以,空EXT2FS的Imap 以10個1開頭,然後是0。無效位再次設定為1。
Block #10:索引(開始)節點塊(bg_inode_table)
每個檔案都用一個128位元組(EXT4中的是256位元組)的獨特索引節點結構體表示。