天天看點

Linux 作業系統原理 — 檔案系統 —檔案

目錄

檔案的類型

正常檔案

ASCII 碼檔案

二進制檔案

裝置檔案

字元裝置檔案

塊裝置檔案

目錄檔案

其他檔案

檔案的構造方式

檔案的屬性

檔案的操作

目錄的操作

正常檔案(Regular files):是包含有使用者資訊的檔案。包括:C 語言元代碼、Shell 腳本、文本檔案、圖像檔案、二進制的可執行檔案等。從正常檔案讀取資料或将資料寫入時,核心會根據檔案系統的規則執行操作,寫入可能被延遲,記錄日志或者接受其他操作。一般分為 ASCII 碼檔案或者二進制檔案。

ASCII 碼檔案:由文本組成。在一些系統中,每行都會用回車符結束(ASCII 碼是 13,控制字元 CR,轉義字元 \r),另外一些則會使用換行符(ASCII 碼是 10,控制字元 LF,轉義字元 \n),也有系統(比如 Windows)兩者都會使用。ASCII 檔案的優點在于顯示 和 列印,還可以用任何文本編輯器進行編輯。進一步來說,如果許多應用程式使用 ASCII 碼作為輸入和輸出,那麼很容易就能夠把多個程式連接配接起來,一個程式的輸出可能是另一個程式的輸入,就像管道一樣。

二進制檔案:取自早期的 UNIX,盡管從技術上來看這個檔案隻是位元組序列,但是作業系統隻有在檔案格式正确的情況下才會執行。

Linux 作業系統原理 — 檔案系統 —檔案

這個檔案有五個段:檔案頭、正文、資料、重定位位和符号表。檔案頭以魔數(magic number)開始,表明這個檔案是一個可執行檔案(以防止意外執行非此格式的檔案)。然後是檔案各個部分的大小,開始執行的标志以及一些标志位。程式本身的正文和資料在檔案頭後面,他們被加載到記憶體中或者重定位會根據重定位位進行判斷。符号表則用于調試(e.g. gdb)。

二進制檔案的另外一種形式是存檔檔案,它由已編譯但沒有連結的庫(子產品)組合而成。每個檔案都以子產品頭開始,其中記錄了名稱、建立日期、所有者、保護碼和檔案大小。和可執行檔案一樣,子產品頭也都是二進制數,将它們複制到列印機将會産生亂碼。

所有的作業系統必須至少能夠識别一種檔案類型:它自己的可執行檔案。以前的 TOPS-20 系統(用于 DECsystem 20)甚至要檢查要執行的任何檔案的建立時間,為了定位資源檔案來檢查自動檔案建立後是否被修改過。如果被修改過了,那麼就會自動編譯檔案。在 UNIX 中,就是在 Shell 中嵌入 make 程式。此時作業系統要求使用者必須采用固定的檔案擴充名,進而确定哪個源程式生成哪個二進制檔案。

什麼是 make 程式?在軟體發展過程中,make 程式是一個自動編譯的工具,它通過讀取稱為 Makefiles 的檔案來自動從源代碼建構可執行程式和庫,該檔案指定了如何導出目标程式。盡管內建開發環境和特定語言的編譯器功能也可以用于管理建構過程,但 Make 仍被廣泛使用,尤其是在 UNIX 和類似 UNIX 的作業系統中使用。

當程式從檔案中讀寫資料時,請求會轉到核心處理程式(Kernel driver)。如果檔案是正常檔案,則資料由檔案系統驅動程式處理,并且通常存儲在磁盤或其他存儲媒體上的某塊區域中,從檔案中讀取的資料就是之前在該位置寫入的資料。

當資料讀取或寫入到裝置檔案時,請求會被裝置驅動程式處理。每個裝置檔案都有一個關聯的編号,該編号标示要使用的裝置驅動程式。裝置處理資料的工作是它自己的事兒。

裝置檔案:與系統外設相關的,通常在 /dev 下面。分為塊裝置和字元裝置。

字元裝置,也稱為字元特殊檔案(Character special file):和輸入/輸出有關,用于串行 I/O 類裝置,如:終端、列印機、網絡等。它的行為類似于管道、串行端口。将位元組寫入字元裝置可能會導緻它在螢幕上顯示,在串行端口上輸出,轉換為聲音。

塊裝置,也稱為塊特殊檔案(block special file):用于磁盤類裝置。它的行為通常與普通檔案相似:它們是位元組數組,并且在給定位置讀取的值是最後寫入該位置的值。來自塊裝置的資料可以緩存在記憶體中,并從緩存中讀取;寫入可以被緩沖。塊裝置通常是可搜尋的,塊裝置的概念是,相應的硬體可以一次讀取或者寫入整個塊,例如磁盤上的一個扇區。

目錄(Directories)是管理檔案系統結構的系統檔案。它是用于在計算機上存儲文,存儲檔案的唯一地方。目錄位于分層檔案系統中,例如 Linux,MS-DOS 和 UNIX。

和 DOS 等作業系統不同,Linux 作業系統中單獨的檔案系統并不是由驅動器号或驅動器名稱(e.g. A:、C: 等)來辨別的。相反,和 UNIX 作業系統一樣,Linux 作業系統将獨立的檔案系統組合成了一個階層化的樹形結構,并且由一個單獨的實體代表這一檔案系統。Linux 将新的檔案系統通過一個稱為 “挂裝” 或 “挂上” 的操作将其挂裝到某個目錄上,進而讓不同的檔案系統結合成為一個整體。

Linux 使用标準的目錄結構,在安裝的時候,安裝程式就已經為使用者建立了檔案系統和完整而固定的目錄結構,并指定了每個目錄的作用和其中的檔案類型。

完整的目錄樹可劃分為小的部分,這些小部分又可以單獨存放在自己的磁盤或分區上。這樣,相對穩定的部分和經常變化的部分可單獨存放在不同的分區中,進而友善備份或系統管理。

Linux 作業系統原理 — 檔案系統 —檔案

Linux 采用的是樹型結構。最上層是根目錄,其他的所有目錄都是從根目錄出發而生成的。在 Linux 中,無論作業系統管理幾個磁盤分區,這樣的目錄樹隻有一個。從結構上講,各個磁盤分區上的樹型目錄不一定是并列的。

/bin:二進制可執行指令

/dev:裝置特殊檔案

/etc:系統管理和配置檔案

/etc/rc.d:啟動的配置檔案和腳本

/home:使用者主目錄的基點

/lib:标準程式設計庫,又叫動态連結共享庫

/sbin:系統管理指令,這裡存放的是系統管理者使用的管理程式

/tmp:公用的臨時檔案存儲點

/root:系統管理者的主目錄

/mnt:系統提供這個目錄是讓使用者臨時挂載其他的檔案系統

/lost+found:這個目錄平時是空的,存放系統在非正常關機情況下而留下 “無家可歸” 的檔案

/proc:虛拟的目錄,是系統記憶體的映射。可直接通路這個目錄來擷取系統資訊。

/var:某些大檔案的溢出區,比方說各種服務的日志檔案

/usr:最龐大的目錄,要用到的應用程式和檔案幾乎都在這個目錄。其中包含:

/usr/X11R6:存放 X window 程式的目錄

/usr/bin:衆多的應用程式

/usr/sbin:root 的一些管理程式

/usr/doc:Linux 文檔

/usr/include:Linux 下開發和編譯應用程式所需要的頭檔案

/usr/lib:常用的動态連結庫和軟體包的配置檔案

/usr/man:幫助文檔

/usr/src:源代碼,Linux 核心的源代碼就放在 /usr/src/linux 下

/usr/local/bin:本地增加的指令

/usr/local/lib:本地增加的庫

連結檔案:指向同一個檔案或目錄的的檔案。

管道(FIFO)檔案 : 提供程序建通信的一種方式。

套接字(Socket) 檔案: 該檔案類型與網絡通信有關。

Linux 作業系統原理 — 檔案系統 —檔案

檔案的構造有多種方式。上圖列出了常用的三種構造方式:

上圖中的 a 是一種無結構的位元組序列,作業系統不關心序列的内容是什麼,作業系統能看到的就是位元組(Bytes)。其檔案内容的任何含義隻在使用者程式中進行解釋。UNIX 和 Windows 都采用這種辦法。把檔案看成位元組序列提供了最大的靈活性。使用者程式可以向檔案中寫任何内容,并且可以通過任何友善的形式命名。作業系統不會為為使用者寫入内容提供幫助,當然也不會幹擾阻塞你。對于想做特殊操作的使用者來說,後者是十分重要的。所有的 UNIX 版本(包括 Linux 和 OS X)和 Windows 都使用這種檔案模型。

圖 b 表示在檔案結構上的第一步改進。在這個模型中,檔案是具有固定長度記錄的序列,每個記錄都有其内部結構。把檔案作為記錄序列的核心思想是:讀操作傳回一個記錄,而寫操作重寫或者追加一個記錄。

第三種檔案結構如上圖 c 所示。在這種組織結構中,檔案由一顆記錄樹構成,記錄樹的長度不一定相同,每個記錄樹都在記錄中的固定位置包含一個key 字段。這棵樹按 key 進行排序,進而可以對特定的 key 進行快速查找。在記錄樹的結構中,可以取出下一個記錄,但是最關鍵的還是根據 key 搜尋指定的記錄。如上圖 c 所示,使用者可以讀出指定的 pony 記錄,而不必關心記錄在檔案中的确切位置。使用者也可以在檔案中添加新的記錄。但是使用者不能決定添加到何處位置,添加到何處位置是由作業系統決定的。

Linux 作業系統原理 — 檔案系統 —檔案

Create,建立不包含任何資料的檔案。調用的目的是表示檔案即将建立,并對檔案設定一些屬性。

Delete,當檔案不再需要,必須删除它以釋放記憶體空間。為此總會有一個系統調用來删除檔案。

Open,在使用檔案之前,必須先打開檔案。這個調用的目的是允許系統将屬性和磁盤位址清單儲存到主存中,用來以後的快速通路。

Close,當所有程序完成時,屬性和磁盤位址不再需要,是以應關閉檔案以釋放表空間。很多系統限制程序打開檔案的個數,以此達到鼓勵使用者關閉不再使用的檔案。磁盤以塊為機關寫入,關閉檔案時會強制寫入最後一塊,即使這個塊空間内部還不滿。

Read,資料從檔案中讀取。通常情況下,讀取的資料來自檔案的目前位置。調用者必須指定需要讀取多少資料,并且提供存放這些資料的緩沖區。

Write,向檔案寫資料,寫操作一般也是從檔案的目前位置開始進行。如果目前位置是檔案的末尾,則會直接追加進行寫入。如果目前位置在檔案中,則現有資料被覆寫,并且永遠消失。

Append,使用 append 隻能向檔案末尾添加資料。

Seek,對于随機通路的檔案,要指定從何處開始擷取資料。通常的方法是用 seek 系統調用把目前位置指針指向檔案中的特定位置。seek 調用結束後,就可以從指定位置開始讀寫資料了。

Get attributes,程序運作時通常需要讀取檔案屬性。

Set attributes,使用者可以自己設定一些檔案屬性,甚至是在檔案建立之後,實作該功能的是 set attributes 系統調用。

Rename,使用者可以自己更改已有檔案的名字,rename 系統調用用于這一目的。

create,建立目錄,除了目錄項 . 和 … 外,目錄内容為空。

delete,删除目錄,隻有空目錄可以删除。隻包含 . 和 … 的目錄被認為是空目錄,這兩個目錄項通常不能删除

opendir,目錄内容可被讀取。例如,未列出目錄中的全部檔案,程式必須先打開該目錄,然後讀其中全部檔案的檔案名。與打開和讀檔案相同,在讀目錄前,必須先打開檔案。

closedir,讀目錄結束後,應該關閉目錄用于釋放内部表空間。

readdir,系統調用 readdir 傳回打開目錄的下一個目錄項。以前也采用 read 系統調用來讀取目錄,但是這種方法有一個缺點:程式員必須了解和處理目錄的内部結構。相反,不論采用哪一種目錄結構,readdir 總是以标準格式傳回一個目錄項。

rename,在很多方面目錄和檔案都相似。檔案可以更換名稱,目錄也可以。

link,連結技術允許在多個目錄中出現同一個檔案。這個系統調用指定一個存在的檔案和一個路徑名,并建立從該檔案到路徑所指名字的連結。這樣,可以在多個目錄中出現同一個檔案。有時也被稱為硬連結(hard link)。

unlink,删除目錄項。如果被解除連結的檔案隻出現在一個目錄中,則将它從檔案中删除。如果它出現在多個目錄中,則隻删除指定路徑名的連結,依然保留其他路徑名的連結。在 UNIX 中,用于删除檔案的系統調用就是 unlink。

繼續閱讀