當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > wenzi嵌入式軟件
[導(dǎo)讀]文件系統(tǒng)定義在計(jì)算機(jī)出現(xiàn)之前其實(shí)就有文件系統(tǒng)的概念了,此時(shí)的文件系統(tǒng)指的是用于管理(存儲(chǔ)和檢索)紙質(zhì)文件的系統(tǒng),而在計(jì)算機(jī)發(fā)明之后,文件系統(tǒng)逐漸指的是管理存儲(chǔ)介質(zhì)的系統(tǒng),它通過(guò)簡(jiǎn)單的接口給用戶,方便用戶使用存儲(chǔ)設(shè)備。在學(xué)習(xí)Linux的時(shí)候,我們通常會(huì)看到這樣一句話,Linux中一...

文件系統(tǒng)定義

在計(jì)算機(jī)出現(xiàn)之前其實(shí)就有文件系統(tǒng)的概念了,此時(shí)的文件系統(tǒng)指的是用于管理(存儲(chǔ)和檢索)紙質(zhì)文件的系統(tǒng),而在計(jì)算機(jī)發(fā)明之后,文件系統(tǒng)逐漸指的是管理存儲(chǔ)介質(zhì)的系統(tǒng),它通過(guò)簡(jiǎn)單的接口給用戶,方便用戶使用存儲(chǔ)設(shè)備。

在學(xué)習(xí) Linux 的時(shí)候,我們通常會(huì)看到這樣一句話,Linux中一切皆文件,也就是說(shuō),不管是普通的文件和目錄,還是包括塊設(shè)備、管道、socket等,也都是交給文件系統(tǒng)去管理的。文件系統(tǒng)是操作系統(tǒng)中負(fù)責(zé)管理持久數(shù)據(jù)的子系統(tǒng),換言之,也就是負(fù)責(zé)把用戶的文件存到磁盤(pán)硬件中,它是一個(gè)磁盤(pán)上的目錄結(jié)構(gòu),是一個(gè)組織文件的方法,并且在一個(gè)磁盤(pán)上,可以包含一個(gè)或者多個(gè)文件系統(tǒng)。

下面,我們從用戶的角度和操作系統(tǒng)的角度兩個(gè)層面來(lái)闡述文件系統(tǒng)的相關(guān)概念。

用戶角度

要認(rèn)識(shí) Linux 的文件系統(tǒng),從分區(qū)和目錄結(jié)構(gòu)說(shuō)起,首先我們先來(lái)看下windows,這是大多數(shù)人使用最多的一個(gè)操作系統(tǒng),當(dāng)打開(kāi)我的電腦的時(shí)候,映入眼簾的是大致是這樣一個(gè)一張圖:

image-20210606083453663
也就是說(shuō)在 windows 下,磁盤(pán)被分為了 C 盤(pán), D 盤(pán)。。。。這樣的一個(gè)目錄結(jié)構(gòu)。那對(duì)于?Linux呢,它的目錄結(jié)構(gòu)是長(zhǎng)啥樣,它有一個(gè)根目錄,而系統(tǒng)下的所有目錄都是從根目錄分離出去的,我們可以在?Ubuntu終端運(yùn)行如下命令來(lái)查看Linux的目錄結(jié)構(gòu)。

tree?-L?1?/
上述中,tree表示將當(dāng)前目錄以樹(shù)的結(jié)構(gòu)展示,-L表示的是要顯示當(dāng)目錄的第幾層,1表示的是要顯示到第一層,最后面的?/表示的也就是Linux的根目錄,也就是說(shuō)當(dāng)前命令就是顯示根目錄下第一層目錄的信息,最終得到的結(jié)果如下所示:

image-20210606084251803
為了更好地理解每個(gè)目錄所代表的意思,我們看如下所示的內(nèi)容:

/
|----bin?????---------------->?文件系統(tǒng)的起始位置,稱之為根
|----boot????---------------->?存放系統(tǒng)啟動(dòng)時(shí)讀取的文件,包括系統(tǒng)核心文件
|----dev?????---------------->?存放設(shè)備文件接口,如打印機(jī),硬盤(pán)等外圍設(shè)備
|----etc?????---------------->?存放與系統(tǒng)設(shè)置和管理相關(guān)的文件,如用戶賬號(hào)、密碼等
|????|
|----home????----------------->?存放用戶專屬目錄
|----lib?????----------------->?存放一些共享的函數(shù)庫(kù)
|----misc????----------------->?一個(gè)空目錄,供管理員存放公共雜物
|----proc????----------------->?存放系統(tǒng)核心和執(zhí)行程序之間的信息
|----root????----------------->?系統(tǒng)管理員(超級(jí)用戶)專用目錄
|----sbin????----------------->?與?/bin?類似,存放用于系統(tǒng)引導(dǎo)和管理命令,通常供?root?使用?
|----tmp?????----------------->?臨時(shí)目錄,供任何用戶存放臨時(shí)文件
|----usr?????----------------->?此目錄包含許多子目錄,用來(lái)存放系統(tǒng)命令和程序等信息
|----var?????----------------->?存放經(jīng)常變動(dòng)的文件,如日志文件,臨時(shí)文件,電子郵箱
說(shuō)到這,就有必要再說(shuō)一下?Linux下的路徑問(wèn)題了,在Linux中,Linux的路徑分為絕對(duì)路徑相對(duì)路徑

  • 絕對(duì)路徑:指的是一個(gè)文件或者目錄從根目錄開(kāi)始的完整的路徑

  • 相對(duì)路徑:是指一個(gè)文件或者目錄相對(duì)于向前工作目錄的路徑

  • 任何不以/~開(kāi)始的路徑均為相對(duì)路徑

說(shuō)完了路徑,接下來(lái)要敘述的就是?Linux的文件類型的,Linux 內(nèi)一切皆文件,那么對(duì)于 Linux 來(lái)說(shuō),其具有哪些文件類型呢,其主要有如下四種:

  • 普通文件

  • 目錄文件

  • 鏈接文件:其作用類似于?windows下的快捷方式,它本身不包含內(nèi)容,而是指向其他的文件或目錄

  • 設(shè)備文件:存放在?/dev目錄下,如:hda,hdb,sda。。。

最后,在平時(shí)使用操作系統(tǒng)的時(shí)候,可能會(huì)涉及到掛載的操作,那掛載是什么意思呢?Linux啟動(dòng)的時(shí)候,首先掛載的是根文件系統(tǒng),之后可以自動(dòng)或者手動(dòng)掛載其他文件系統(tǒng),這些文件系統(tǒng)要掛載到掛載點(diǎn)上,與虛擬文件系統(tǒng)和通用塊設(shè)備層建立聯(lián)系。

掛載,指的就是將設(shè)備文件中的頂級(jí)目錄連接到 Linux 根目錄下的某一目錄(最好是空目錄),訪問(wèn)此目錄就等同于訪問(wèn)設(shè)備文件。

上述就是基于用戶的角度對(duì)文件系統(tǒng)進(jìn)行了一個(gè)概述,接下來(lái)從操作系統(tǒng)的角度,更進(jìn)一步地闡述操作系統(tǒng)。

操作系統(tǒng)角度

文件系統(tǒng)的層次

在上述中,闡述掛載的時(shí)候說(shuō)到一個(gè)概念,就是說(shuō)?Linux在啟動(dòng)的時(shí)候,首先掛載的是根文件系統(tǒng),然后再自動(dòng)或者手動(dòng)掛載其他文件系統(tǒng),這也是Linux中支持不同文件系統(tǒng)的原因,而支持各種不同文件系統(tǒng)的這種機(jī)制又是什么呢?說(shuō)到這里,就有必要提到Linux的虛擬文件系統(tǒng)了,再敘述它的概念之前,我們先以宏觀的角度來(lái)看一下?Linux下的文件系統(tǒng)的一個(gè)結(jié)構(gòu):

image-20210606105240091
由上圖可以知道,整個(gè)文件系統(tǒng)體系分為了三個(gè)層面,用戶層,內(nèi)核層,硬件層,用戶層是通過(guò)API通過(guò)系統(tǒng)調(diào)用調(diào)用的方式訪問(wèn)虛擬文件系統(tǒng)。在內(nèi)核層,我們可以看到虛擬文件系統(tǒng)下連接了各種類型的文件系統(tǒng),其是對(duì)不同的文件系統(tǒng)的抽象,為上層應(yīng)用提供了統(tǒng)一的 API 接口;上圖內(nèi)核層還有一層是各個(gè)文件系統(tǒng)之下的一層,這一層的作用是隱藏了不同硬件設(shè)備之間的細(xì)節(jié),為內(nèi)核提供了統(tǒng)一的 IO 操作接口。下面我們對(duì)整個(gè)文件系統(tǒng)從下到上對(duì)各個(gè)層的作用進(jìn)行一個(gè)闡述:

  • Device Driver(硬盤(pán)驅(qū)動(dòng)):常見(jiàn)的硬盤(pán)類型有PATA,SATA,在Linux中,對(duì)于硬盤(pán)提供的驅(qū)動(dòng)模塊一般都存放在內(nèi)核目錄樹(shù)drivers/ata中,而對(duì)于一般通用的硬盤(pán)驅(qū)動(dòng),可能會(huì)直接被編譯到內(nèi)核中。

  • 通用塊設(shè)備層(General Block Device Layer):不同的硬盤(pán),會(huì)提供不同的 IO 接口,對(duì)于內(nèi)核來(lái)講,這種雜亂的接口是不利于管理的,因此就把這些接口進(jìn)行了抽象,形成了一個(gè)統(tǒng)一的對(duì)外接口,這樣就不管你是什么存儲(chǔ)設(shè)備,操作他們的IO接口并沒(méi)有什么區(qū)別。

  • 文件系統(tǒng)層:目前大多數(shù)Linux使用的是ex4,與此同時(shí),btrfs也呼之欲出

  • 虛擬文件系統(tǒng):正如不同的存儲(chǔ)設(shè)備具有不同的 IO 接口,那么不同的文件系統(tǒng)也具有不用的 API,內(nèi)核想實(shí)現(xiàn)的是不管是什么文件系統(tǒng),都采用的是相同的 API 進(jìn)行操作,所以 VFS 就做了一個(gè)抽象,提供了統(tǒng)一的 API 接口,使之可以對(duì)不同的文件系統(tǒng)采用同樣的操作。

文件的使用

上述中,我們介紹了文件系統(tǒng)的層次,那么基于這樣一個(gè)層次,我們又應(yīng)該如何使用文件呢?下圖是一個(gè)使用文件的流程圖:

image-20210606131958026
與其對(duì)應(yīng)的代碼也比較簡(jiǎn)單:

fd?=?open(name,?flag);????/*?打開(kāi)文件?*/
...
write(fd,?...);???????????/*?寫(xiě)數(shù)據(jù)?*/
...
close(fd);????????????????/*?關(guān)閉文件?*/
上述就是往一個(gè)文件中寫(xiě)數(shù)據(jù)的步驟,使用open系統(tǒng)調(diào)用打開(kāi)文件,open的參數(shù)中包含文件的路徑名和文件名,使用write寫(xiě)數(shù)據(jù),其中write使用open所返回的文件描述符,使用完文件后,用close系統(tǒng)關(guān)閉文件,避免資源的泄露。

在打開(kāi)了一個(gè)文件后,操作系統(tǒng)會(huì)跟蹤進(jìn)程打開(kāi)的所有文件,也就是說(shuō)操作系統(tǒng)為每個(gè)進(jìn)程維護(hù)一個(gè)打開(kāi)文件表,文件表里的每一項(xiàng)代表的是文件描述符,所以說(shuō)文件描述符是打開(kāi)文件的標(biāo)識(shí)。

image-20210606133042481
操作系統(tǒng)在打開(kāi)文件表中維護(hù)著打開(kāi)文件的狀態(tài)和信息:

  • 文件指針:系統(tǒng)跟蹤上次讀寫(xiě)位置作為當(dāng)前文件位置的指針,這個(gè)指針對(duì)于打開(kāi)文件的某個(gè)進(jìn)程來(lái)說(shuō)是唯一的;

  • 文件打開(kāi)計(jì)數(shù)器:文件關(guān)閉時(shí),操作系統(tǒng)必須重用其打開(kāi)文件表目錄,否則表內(nèi)空間就不夠。因?yàn)槎鄠€(gè)進(jìn)程可能打開(kāi)同一個(gè)文件,所以系統(tǒng)在刪除打開(kāi)文件條目之前,必須等待最后一個(gè)進(jìn)程關(guān)閉文件,該計(jì)數(shù)器跟蹤打開(kāi)和關(guān)閉數(shù)量,當(dāng)該計(jì)數(shù)為 0 時(shí),系統(tǒng)關(guān)閉文件,刪除該條目;

  • 文件磁盤(pán)位置:大多數(shù)文件操作都需要系統(tǒng)修改文件的數(shù)據(jù),該信息保存在內(nèi)存中,以免每個(gè)操作都從磁盤(pán)中讀?。?/span>

  • 訪問(wèn)權(quán)限:每個(gè)進(jìn)程打開(kāi)文件都需要又一個(gè)訪問(wèn)模式(創(chuàng)建、只讀、讀寫(xiě)、添加等),該信息保存在進(jìn)程的打開(kāi)文件表中。

文件系統(tǒng)的IO類型

根據(jù)文件系統(tǒng)的讀寫(xiě)差異,可以將IO分為四種類型:

  • 緩沖 I/O:是指利用標(biāo)準(zhǔn)庫(kù)緩存來(lái)加速文件的訪問(wèn),而標(biāo)準(zhǔn)庫(kù)內(nèi)部再通過(guò)系統(tǒng)調(diào)度訪問(wèn)文件。

  • 非緩沖I/O:是指直接通過(guò)系統(tǒng)調(diào)用來(lái)訪問(wèn)文件,不再經(jīng)過(guò)標(biāo)準(zhǔn)庫(kù)緩存

此處標(biāo)準(zhǔn)庫(kù)緩存指的是利用棧、隊(duì)列等一些數(shù)據(jù)結(jié)構(gòu)進(jìn)行的資源調(diào)度,而不是頁(yè)緩存。無(wú)論是否是緩沖IO,都會(huì)通過(guò)系統(tǒng)調(diào)用頁(yè)緩存來(lái)減少IO次數(shù)

根據(jù)是否利用操作系統(tǒng)的頁(yè)緩存,可以把文件I/O分為直接I/O非直接I/O

  • 直接I/O:是指跳過(guò)操作系統(tǒng)的頁(yè)緩存,直接跟文件系統(tǒng)交互來(lái)訪問(wèn)文件

  • 非直接I/O:文件讀寫(xiě)的時(shí)候,先要經(jīng)過(guò)系統(tǒng)的頁(yè)緩存,然后再由內(nèi)核或者是額外的系統(tǒng)調(diào)用,真正寫(xiě)入存儲(chǔ)設(shè)備

通常,我們的 IO 都是非直接I/O

根據(jù)應(yīng)用程序是都阻塞自身運(yùn)行,可以把文件 I/O 分為阻塞 I/O 和非阻塞 I/O

  • 阻塞I/O,是指應(yīng)用程序執(zhí)行 I/O 操作之后,如果沒(méi)有獲得響應(yīng),就會(huì)阻塞當(dāng)前的線程,自然不能執(zhí)行其他任務(wù)

  • 非阻塞I/O,是指應(yīng)用程序執(zhí)行 I/O 操作之后,不會(huì)阻塞當(dāng)前的線程,可以繼續(xù)執(zhí)行其他的任務(wù),隨后再通過(guò)輪詢或者事件通知的形式,獲得調(diào)用的結(jié)果

通常情況下I/O都是阻塞的。網(wǎng)絡(luò)編程中是非阻塞的I/O,用在網(wǎng)絡(luò)套接字的 I/O 中

根據(jù)是否等待響應(yīng)結(jié)果,把文件分為同步IO和異步IO

  • 同步IO:應(yīng)用程序在執(zhí)行IO操作之后,要一直等到整個(gè)IO完成后,才獲得 IO 響應(yīng)

  • 異步IO:是指應(yīng)用程序在執(zhí)行IO操作之后,不用等待完成,可以繼續(xù)做之后的事情,等到 IO 完成的時(shí)候,會(huì)通過(guò)事件通知的方式,告訴應(yīng)用程序

文件的存儲(chǔ)

Linux中所有文件都有一個(gè)唯一與之對(duì)應(yīng)的索引節(jié)點(diǎn),索引節(jié)點(diǎn)記錄了文件的元數(shù)據(jù),操作系統(tǒng)不是通過(guò)文件名,而是通過(guò)索引節(jié)點(diǎn)來(lái)管理文件,用目錄項(xiàng)來(lái)描述文件之間的關(guān)系。

索引節(jié)點(diǎn),也被稱之為是inode,用來(lái)記錄文件的元數(shù)據(jù),元數(shù)據(jù)就包括:node編號(hào)、文件大小、訪問(wèn)權(quán)限、修改日期、數(shù)據(jù)的位置等。

目錄項(xiàng),也被稱為dentry,用來(lái)記錄文件的名字、索引節(jié)點(diǎn)指針及與其他目錄項(xiàng)的關(guān)聯(lián)關(guān)系。多個(gè)關(guān)聯(lián)的目錄項(xiàng),也就構(gòu)成了文件系統(tǒng)的目錄結(jié)構(gòu)。

因此,索引節(jié)點(diǎn)相當(dāng)?shù)挠谖募闹羔?,目錄?xiàng)維護(hù)著文件的樹(shù)型關(guān)系

下面是文件存儲(chǔ)各個(gè)部分邏輯關(guān)系的一個(gè)示意圖:

image-20210606145357280
上圖中,超級(jí)塊用來(lái)存儲(chǔ)著整個(gè)文件系統(tǒng)的狀態(tài),索引節(jié)點(diǎn)區(qū)用來(lái)存儲(chǔ)索引節(jié)點(diǎn),數(shù)據(jù)塊區(qū)用來(lái)存儲(chǔ)文件的數(shù)據(jù),他們之間的關(guān)系在圖中也很清除了,就不進(jìn)行贅述了。

總結(jié)

Linux是一個(gè)很龐大也很優(yōu)秀的系統(tǒng),在嵌入式行業(yè)也應(yīng)用廣泛,筆者對(duì)于?Linux的接觸不深,這也是最近對(duì)于學(xué)習(xí)?Linux文件系統(tǒng)時(shí)的一個(gè)總結(jié),如果文中出現(xiàn)問(wèn)題,歡迎各位及時(shí)給我提出來(lái)呀,我將不勝感激~


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉