又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

這是Java建設者的第 77 篇原創文章node

文件系統的實現
在對文件有了基本認識以後,如今是時候把目光轉移到文件系統的實現上了。以前用戶關心的一直都是文件是怎樣命名的、能夠進行哪些操做、目錄樹是什麼,如何找到正確的文件路徑等問題。而設計人員關心的是文件和目錄是怎樣存儲的、磁盤空間是如何管理的、如何使文件系統得以流暢運行的問題,下面咱們就來一塊兒討論一下這些問題。數組

文件系統佈局
文件系統存儲在磁盤中。大部分的磁盤可以劃分出一到多個分區,叫作磁盤分區(disk partitioning) 或者是磁盤分片(disk slicing)。每一個分區都有獨立的文件系統,每塊分區的文件系統能夠不一樣。磁盤的 0 號分區稱爲 主引導記錄(Master Boot Record, MBR),用來引導(boot) 計算機。在 MBR 的結尾是分區表(partition table)。每一個分區表給出每一個分區由開始到結束的地址。系統管理員使用一個稱爲分區編輯器的程序來建立,調整大小,刪除和操做分區。這種方式的一個缺點是很難適當調整分區的大小,致使一個分區具備不少可用空間,而另外一個分區幾乎徹底被分配。緩存

「MBR 能夠用在 DOS 、Microsoft Windows 和 Linux 操做系統中。從 2010 年代中期開始,大多數新計算機都改用 GUID 分區表(GPT)分區方案。
下面是一個用 GParted 進行分區的磁盤,表中的分區都被認爲是 活動的(active)。
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統安全

當計算機開始 boot 時,BIOS 讀入並執行 MBR。網絡

引導塊
MBR 作的第一件事就是肯定活動分區,讀入它的第一個塊,稱爲引導塊(boot block) 並執行。引導塊中的程序將加載分區中的操做系統。爲了一致性,每一個分區都會從引導塊開始,即便引導塊不包含操做系統。引導塊佔據文件系統的前 4096 個字節,從磁盤上的字節偏移量 0 開始。引導塊可用於啓動操做系統。數據結構

「在計算機中,引導就是啓動計算機的過程,它能夠經過硬件(例如按下電源按鈕)或者軟件命令的方式來啓動。開機後,電腦的 CPU 還不能執行指令,由於此時沒有軟件在主存中,因此一些軟件必須先被加載到內存中,而後才能讓 CPU 開始執行。也就是計算機開機後,首先會進行軟件的裝載過程。重啓電腦的過程稱爲從新引導(rebooting),從休眠或睡眠狀態返回計算機的過程不涉及啓動。
除了從引導塊開始以外,磁盤分區的佈局是隨着文件系統的不一樣而變化的。一般文件系統會包含一些屬性,以下
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統編輯器

超級塊
緊跟在引導塊後面的是 超級塊(Superblock),超級塊的大小爲 4096 字節,從磁盤上的字節偏移 4096 開始。超級塊包含文件系統的全部關鍵參數ide

  • 文件系統的大小
  • 文件系統中的數據塊數
  • 指示文件系統狀態的標誌
  • 分配組大小
    在計算機啓動或者文件系統首次使用時,超級塊會被讀入內存。

空閒空間塊
接着是文件系統中空閒塊的信息,例如,能夠用位圖或者指針列表的形式給出。佈局

BitMap 位圖或者 Bit vector 位向量性能

位圖或位向量是一系列位或位的集合,其中每一個位對應一個磁盤塊,該位能夠採用兩個值:0和1,0表示已分配該塊,而1表示一個空閒塊。下圖中的磁盤上給定的磁盤塊實例(分配了綠色塊)能夠用16位的位圖表示爲:0000111000000110。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

使用鏈表進行管理

在這種方法中,空閒磁盤塊連接在一塊兒,即一個空閒塊包含指向下一個空閒塊的指針。第一個磁盤塊的塊號存儲在磁盤上的單獨位置,也緩存在內存中。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

碎片

這裏不得不提一個叫作碎片(fragment)的概念,也稱爲片斷。通常零散的單個數據一般稱爲片斷。磁盤塊能夠進一步分爲固定大小的分配單元,片斷只是在驅動器上彼此不相鄰的文件片斷。若是你不理解這個概念就給你舉個例子。好比你用 Windows 電腦建立了一個文件,你會發現這個文件能夠存儲在任何地方,好比存在桌面上,存在磁盤中的文件夾中或者其餘地方。你能夠打開文件,編輯文件,刪除文件等等。你可能覺得這些都在一個地方發生,可是實際上並非,你的硬盤驅動器可能會將文件中的一部分存儲在一個區域內,另外一部分存儲在另一個區域,在你打開文件時,硬盤驅動器會迅速的將文件的全部部分彙總在一塊兒,以便其餘計算機系統可使用它。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

inode

而後在後面是一個 inode(index node),也稱做索引節點。它是一個數組的結構,每一個文件有一個 inode,inode 很是重要,它說明了文件的方方面面。每一個索引節點都存儲對象數據的屬性和磁盤塊位置

有一種簡單的方法能夠找到它們 ls -lai 命令。讓咱們看一下根文件系統:

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

inode 節點主要包括瞭如下信息

  • 模式/權限(保護)
  • 全部者 ID
  • 組 ID
  • 文件大小
  • 文件的硬連接數
  • 上次訪問時間
  • 最後修改時間
  • inode 上次修改時間
    文件分爲兩部分,索引節點和塊。一旦建立後,每種類型的塊數是固定的。你不能增長分區上 inode 的數量,也不能增長磁盤塊的數量。

緊跟在 inode 後面的是根目錄,它存放的是文件系統目錄樹的根部。最後,磁盤的其餘部分存放了其餘全部的目錄和文件。

文件的實現
最重要的問題是記錄各個文件分別用到了哪些磁盤塊。不一樣的系統採用了不一樣的方法。下面咱們會探討一下這些方式。分配背後的主要思想是有效利用文件空間和快速訪問文件 ,主要有三種分配方案

  • 連續分配
  • 鏈表分配
  • 索引分配
    連續分配
    最簡單的分配方案是把每一個文件做爲一連串連續數據塊存儲在磁盤上。所以,在具備 1KB 塊的磁盤上,將爲 50 KB 文件分配 50 個連續塊。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

上面展現了 40 個連續的內存塊。從最左側的 0 塊開始。初始狀態下,尚未裝載文件,所以磁盤是空的。接着,從磁盤開始處(塊 0 )處開始寫入佔用 4 塊長度的內存 A 。而後是一個佔用 6 塊長度的內存 B,會直接在 A 的末尾開始寫。

注意每一個文件都會在新的文件塊開始寫,因此若是文件 A 只佔用了 3 又 1/2 個塊,那麼最後一個塊的部份內存會被浪費。在上面這幅圖中,總共展現了 7 個文件,每一個文件都會從上個文件的末尾塊開始寫新的文件塊。

連續的磁盤空間分配有兩個優勢。

  • 第一,連續文件存儲實現起來比較簡單,只須要記住兩個數字就能夠:一個是第一個塊的文件地址和文件的塊數量。給定第一個塊的編號,能夠經過簡單的加法找到任何其餘塊的編號。

  • 第二點是讀取性能比較強,能夠經過一次操做從文件中讀取整個文件。只須要一次尋找第一個塊。後面就再也不須要尋道時間和旋轉延遲,因此數據會以全帶寬進入磁盤。

所以,連續的空間分配具備實現簡單、高性能的特色。

不幸的是,連續空間分配也有很明顯的不足。隨着時間的推移,磁盤會變得很零碎。下圖解釋了這種現象

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

這裏有兩個文件 D 和 F 被刪除了。當刪除一個文件時,此文件所佔用的塊也隨之釋放,就會在磁盤空間中留下一些空閒塊。磁盤並不會在這個位置擠壓掉空閒塊,由於這會複製空閒塊以後的全部文件,可能會有上百萬的塊,這個量級就太大了。

剛開始的時候,這個碎片不是問題,由於每一個新文件都會在以前文件的結尾處進行寫入。然而,磁盤最終會被填滿,所以要麼壓縮磁盤、要麼從新使用空閒塊的空間。壓縮磁盤的開銷太大,所以不可行;後者會維護一個空閒列表,這個是可行的。可是這種狀況又存在一個問題,爲空閒塊匹配合適大小的文件,須要知道該文件的最終大小。

想象一下這種設計的結果會是怎樣的。用戶啓動 word 進程建立文檔。應用程序首先會詢問最終建立的文檔會有多大。這個問題必須回答,不然應用程序就不會繼續執行。若是空閒塊的大小要比文件的大小小,程序就會終止。由於所使用的磁盤空間已經滿了。那麼現實生活中,有沒有使用連續分配內存的介質出現呢?

CD-ROM 就普遍的使用了連續分配方式。

「CD-ROM(Compact Disc Read-Only Memory)即只讀光盤,也稱做只讀存儲器。是一種在電腦上使用的光碟。這種光碟只能寫入數據一次,信息將永久保存在光碟上,使用時經過光碟驅動器讀出信息。
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

然而 DVD 的狀況會更加複雜一些。原則上,一個 90分鐘 的電影可以被編碼成一個獨立的、大約 4.5 GB 的文件。可是文件系統所使用的 UDF(Universal Disk Format) 格式,使用一個 30 位的數來表明文件長度,從而把文件大小限制在 1 GB。因此,DVD 電影通常存儲在 三、4個連續的 1 GB 空間內。這些構成單個電影中的文件塊稱爲擴展區(extends)。
就像咱們反覆提到的,歷史老是驚人的類似,許多年前,連續分配因爲其簡單和高性能被實際使用在磁盤文件系統中。後來因爲用戶不但願在建立文件時指定文件的大小,因而放棄了這種想法。可是隨着 CD-ROM 、DVD、藍光光盤等光學介質的出現,連續分配又流行起來。從而得出結論,技術永遠沒有過期性,如今看似很老的技術,在將來某個階段可能又會流行起來。

鏈表分配
第二種存儲文件的方式是爲每一個文件構造磁盤塊鏈表,每一個文件都是磁盤塊的連接列表,就像下面所示

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

每一個塊的第一個字做爲指向下一塊的指針,塊的其餘部分存放數據。若是上面這張圖你看的不是很清楚的話,能夠看看整個的鏈表分配方案

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

與連續分配方案不一樣,這一方法能夠充分利用每一個磁盤塊。除了最後一個磁盤塊外,不會由於磁盤碎片而浪費存儲空間。一樣,在目錄項中,只要存儲了第一個文件塊,那麼其餘文件塊也可以被找到。

另外一方面,在鏈表的分配方案中,儘管順序讀取很是方便,可是隨機訪問卻很困難(這也是數組和鏈表數據結構的一大區別)。

還有一個問題是,因爲指針會佔用一些字節,每一個磁盤塊實際存儲數據的字節數並再也不是 2 的整數次冪。雖然這個問題並不會很嚴重,可是這種方式下降了程序運行效率。許多程序都是以長度爲 2 的整數次冪來讀寫磁盤,因爲每一個塊的前幾個字節被指針所使用,因此要讀出一個完成的塊大小信息,就須要當前塊的信息和下一塊的信息拼湊而成,所以就引起了查找和拼接的開銷。

使用內存表進行鏈表分配
因爲連續分配和鏈表分配都有其不可忽視的缺點。因此提出了使用內存中的表來解決分配問題。取出每一個磁盤塊的指針字,把它們放在內存的一個表中,就能夠解決上述鏈表的兩個不足之處。下面是一個例子

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

上圖表示了鏈表造成的磁盤塊的內容。這兩個圖中都有兩個文件,文件 A 依次使用了磁盤塊地址 四、七、 二、 十、 12,文件 B 使用了六、三、11 和 14。也就是說,文件 A 從地址 4 處開始,順着鏈表走就能找到文件 A 的所有磁盤塊。一樣,從第 6 塊開始,順着鏈走到最後,也可以找到文件 B 的所有磁盤塊。你會發現,這兩個鏈表都以不屬於有效磁盤編號的特殊標記(-1)結束。內存中的這種表格稱爲 文件分配表(File Application Table,FAT)。

使用這種組織方式,整個塊均可以存放數據。進而,隨機訪問也容易不少。雖然仍要順着鏈在內存中查找給定的偏移量,可是整個鏈都存放在內存中,因此不須要任何磁盤引用。與前面的方法相同,無論文件有多大,在目錄項中只需記錄一個整數(起始塊號),按照它就能夠找到文件的所有塊。

這種方式存在缺點,那就是必需要把整個鏈表放在內存中。對於 1TB 的磁盤和 1KB 的大小的塊,那麼這張表須要有 10 億項。。。每一項對應於這 10 億個磁盤塊中的一塊。每項至少 3 個字節,爲了提升查找速度,有時須要 4 個字節。根據系統對空間或時間的優化方案,這張表要佔用 3GB 或 2.4GB 的內存。FAT 的管理方式不能較好地擴展並應用於大型磁盤中。而這正是最初 MS-DOS 文件比較實用,並仍被各個 Windows 版本所安全支持。

inode
最後一個記錄各個文件分別包含哪些磁盤塊的方法是給每一個文件賦予一個稱爲 inode 的數據結構,它會列出全部文件塊的屬性和地址空間,下面是一個簡單例子的描述。
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

給出 inode 的長度,就可以找到文件中的全部塊。

相對於在內存中使用表的方式而言,這種機制具備很大的優點。即只有在文件打開時,其 inode 纔會在內存中。若是每一個 inode 須要 n 個字節,最多 k 個文件同時打開,那麼 inode 佔有總共打開的文件是 kn 字節。僅需預留這麼多空間。

這個數組要比咱們上面描述的 FAT(文件分配表) 佔用的空間小的多。緣由是用於保存全部磁盤塊的連接列表的表的大小與磁盤自己成正比。若是磁盤有 n 個塊,那麼這個表也須要 n 項。隨着磁盤空間的變大,那麼該表也隨之線性增加。相反,inode 須要節點中的數組,其大小和可能須要打開的最大文件個數成正比。它與磁盤是 100GB、4000GB 仍是 10000GB 無關。

inode 的一個問題是若是每一個節點都會有固定大小的磁盤地址,那麼文件增加到所能容許的最大容量外會發生什麼?一個解決方案是最後一個磁盤地址不指向數據塊,而是指向一個包含額外磁盤塊地址的地址,如上圖所示。一個更高級的解決方案是:有兩個或者更多包含磁盤地址的塊,或者指向其餘存放地址的磁盤塊的磁盤塊。Windows 的 NTFS 文件系統採用了類似的方法,所不一樣的僅僅是大的 inode 也能夠表示小的文件。

目錄的實現
文件只有打開後纔可以被讀取。在文件打開後,操做系統會使用用戶提供的路徑名來定位磁盤中的目錄。目錄項提供了查找文件磁盤塊所須要的信息。根據系統的不一樣,提供的信息也不一樣,可能提供的信息是整個文件的磁盤地址,或者是第一個塊的數量(兩個鏈表方案)或 inode的數量。不過無論用那種狀況,目錄系統的主要功能就是 將文件的 ASCII 碼的名稱映射到定位數據所需的信息上。

與此關係密切的問題是屬性應該存放在哪裏。每一個文件系統包含不一樣的文件屬性,例如文件的全部者和建立時間,須要存儲的位置。一種顯而易見的方法是直接把文件屬性存放在目錄中。有一些系統剛好是這麼作的,以下。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

在這種簡單的設計中,目錄有一個固定大小的目錄項列表,每一個文件對應一項,其中包含一個固定長度的文件名,文件屬性的結構體以及用以說明磁盤塊位置的一個或多個磁盤地址。

對於採用 inode 的系統,會把 inode 存儲在屬性中而不是目錄項中。在這種狀況下,目錄項會更短:僅僅只有文件名稱和 inode 數量。這種方式以下所示

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

到目前爲止,咱們已經假設文件具備較短的、固定長度的名字。在 MS-DOS 中,具備 1 - 8 個字符的基本名稱和 1 - 3 個字符的可拓展名稱。在 UNIX 版本 7 中,文件有 1 - 14 個字符,包括任何拓展。然而,幾乎全部的現代操做系統都支持可變長度的擴展名。這是如何實現的呢?

最簡單的方式是給予文件名一個長度限制,好比 255 個字符,而後使用上圖中的設計,併爲每一個文件名保留 255 個字符空間。這種處理很簡單,可是浪費了大量的目錄空間,由於只有不多的文件會有那麼長的文件名稱。因此,須要一種其餘的結構來處理。

一種可選擇的方式是放棄全部目錄項大小相同的想法。在這種方法中,每一個目錄項都包含一個固定部分,這個固定部分一般以目錄項的長度開始,後面是固定格式的數據,一般包括全部者、建立時間、保護信息和其餘屬性。這個固定長度的頭的後面是一個任意長度的實際文件名,以下圖所示

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

上圖是 SPARC 機器使用正序放置。

「處理機中的一串字符存放的順序有正序(big-endian) 和逆序(little-endian) 之分。正序存放的就是高字節在前低字節在後,而逆序存放的就是低字節在前高字節在後。
這個例子中,有三個文件,分別是 project-budget、personnel 和 foo。每一個文件名以一個特殊字符(一般是 0 )結束,用矩形中的叉進行表示。爲了使每一個目錄項從字的邊界開始,每一個文件名被填充成整數個字,以下圖所示

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

這個方法的缺點是當文件被移除後,就會留下一塊固定長度的空間,而新添加進來的文件大小不必定和空閒空間大小一致。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

這個問題與咱們上面探討的連續磁盤文件的問題是同樣的,因爲整個目錄在內存中,因此只有對目錄進行緊湊拼接操做纔可節省空間。另外一個問題是,一個目錄項可能會分佈在多個頁上,在讀取文件名時可能發生缺頁中斷。

處理可變長度文件名字的另一種方法是,使目錄項自身具備固定長度,而將文件名放在目錄末尾的堆棧中。如上圖所示的這種方式。這種方法的優勢是當目錄項被移除後,下一個文件將可以正常匹配移除文件的空間。固然,必需要對堆進行管理,由於在處理文件名的時候也會發生缺頁異常。

到目前爲止的全部設計中,在須要查找文件名時,全部的方案都是線性的從頭至尾對目錄進行搜索。對於特別長的目錄,線性搜索的效率很低。提升文件檢索效率的一種方式是在每一個目錄上使用哈希表(hash table),也叫作散列表。咱們假設表的大小爲 n,在輸入文件名時,文件名被散列在 0 和 n - 1 之間,例如,它被 n 除,並取餘數。或者對構成文件名字的字求和或相似某種方法。

不管採用哪一種方式,在添加一個文件時都要對與散列值相對應的散列表進行檢查。若是沒有使用過,就會將一個指向目錄項的指針指向這裏。文件目錄項緊跟着哈希表後面。若是已經使用過,就會構造一個鏈表(這種構造方式是否是和 HashMap 使用的數據結構同樣?),鏈表的表頭指針存放在表項中,並經過哈希值將全部的表項相連。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

查找文件的過程和添加相似,首先對文件名進行哈希處理,在哈希表中查找是否有這個哈希值,若是有的話,就檢查這條鏈上全部的哈希項,查看文件名是否存在。若是哈希不在鏈上,那麼文件就不在目錄中。

使用哈希表的優點是查找很是迅速,缺點是管理起來很是複雜。只有在系統中會有成千上萬個目錄項存在時,纔會考慮使用散列表做爲解決方案。

另一種在大量目錄中加快查找指令目錄的方法是使用緩存,緩存查找的結果。在開始查找以前,會首先檢查文件名是否在緩存中。若是在緩存中,那麼文件就能馬上定位。固然,只有在較少的文件下進行屢次查找,緩存纔會發揮最大功效。

共享文件
當多個用戶在同一個項目中工做時,他們一般須要共享文件。若是這個共享文件同時出如今多個用戶目錄下,那麼他們協同工做起來就很方便。下面的這張圖咱們在上面提到過,可是有一個更改的地方,就是 C 的一個文件也出如今了 B 的目錄下。
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

若是按照如上圖的這種組織方式而言,那麼 B 的目錄與該共享文件的聯繫稱爲 連接(link)。那麼文件系統如今就是一個 有向無環圖(Directed Acyclic Graph, 簡稱 DAG),而不是一棵樹了。

「在圖論中,若是一個有向圖從任意頂點出發沒法通過若干條邊回到該點,則這個圖是一個有向無環圖,咱們不會在此着重探討關於圖論的東西,你們能夠自行 google。
將文件系統組織成爲有向無環圖會使得維護複雜化,但也是必需要付出的代價。

共享文件很方便,但這也會帶來一些問題。若是目錄中包含磁盤地址,則當連接文件時,必須把 C 目錄中的磁盤地址複製到 B 目錄中。若是 B 或者 C 隨後又向文件中添加內容,則僅在執行追加的用戶的目錄中顯示新寫入的數據塊。這種變動將會對其餘用戶不可見,從而破壞了共享的目的。
又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

有兩種方案能夠解決這種問題。

  • 第一種解決方案,磁盤塊不列入目錄中,而是會把磁盤塊放在與文件自己相關聯的小型數據結構中。目錄將指向這個小型數據結構。這是 UNIX 中使用的方式(小型數據結構就是 inode)。

  • 在第二種解決方案中,經過讓系統創建一個類型爲 LINK 的新文件,並把該文件放在 B 的目錄下,使得 B 與 C 創建連接。新的文件中只包含了它所連接的文件的路徑名。當 B 想要讀取文件時,操做系統會檢查 B 的目錄下存在一個類型爲 LINK 的文件,進而找到該連接的文件和路徑名,而後再去讀文件,這種方式稱爲 符號連接(symbolic linking)。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

上面的每一種方法都有各自的缺點,在第一種方式中,B 連接到共享文件時,inode 記錄文件的全部者爲 C。創建一個連接並不改變全部關係,以下圖所示。

又來搞事情了,此次女朋友讓我研究如何實現一個文件系統

第一開始的狀況如圖 a 所示,此時 C 的目錄的全部者是 C ,當目錄 B 連接到共享文件時,並不會改變 C 的全部者關係,只是把計數 + 1,因此此時 系統知道目前有多少個目錄指向這個文件。而後 C 嘗試刪除這個文件,這個時候有個問題,若是 C 把文件移除並清除了 inode 的話,那麼 B 會有一個目錄項指向無效的節點。若是 inode 之後分配給另外一個文件,則 B 的連接指向一個錯誤的文件。系統經過 inode 可知文件仍在被引用,可是沒有辦法找到該文件的所有目錄項以刪除它們。指向目錄的指針不能存儲在 inode 中,緣由是有可能有無數個這樣的目錄。

因此咱們能作的就是刪除 C 的目錄項,可是將 inode 保留下來,並將計數設置爲 1 ,如上圖 c 所示。c 表示的是隻有 B 有指向該文件的目錄項,而該文件的前者是 C 。若是系統進行記帳操做的話,那麼 C 將繼續爲該文件付帳直到 B 決定刪除它,若是是這樣的話,只有到計數變爲 0 的時刻,纔會刪除該文件。

對於符號連接,以上問題不會發生,只有真正的文件全部者纔有一個指向 inode 的指針。連接到該文件上的用戶只有路徑名,沒有指向 inode 的指針。當文件全部者刪除文件時,該文件被銷燬。之後若試圖經過符號連接訪問該文件將會失敗,由於系統不能找到該文件。刪除符號連接不會影響該文件。

符號連接的問題是須要額外的開銷。必須讀取包含路徑的文件,而後要一個部分接一個部分地掃描路徑,直到找到 inode 。這些操做也許須要不少次額外的磁盤訪問。此外,每一個符號連接都須要額外的 inode ,以及額外的一個磁盤塊用於存儲路徑,雖然若是路徑名很短,做爲一種優化,系統能夠將它存儲在 inode 中。符號連接有一個優點,即只要簡單地提供一個機器的網絡地址以及文件在該機器上駐留的路徑,就能夠鏈接全球任何地方機器上的文件。

還有另外一個由連接帶來的問題,在符號連接和其餘方式中都存在。若是容許連接,文件有兩個或多個路徑。查找一指定目錄及其子目錄下的所有文件的程序將屢次定位到被連接的文件。例如,一個將某一目錄及其子目錄下的文件轉存到磁帶上的程序有可能屢次複製一個被連接的文件。進而,若是接着把磁帶讀入另外一臺機器,除非轉出程序具備智能,不然被連接的文件將被兩次複製到磁盤上,而不是隻是被連接起來。

相關文章
相關標籤/搜索