Linux檔案操作(innode與軟硬連結)

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第9天

零.前言

上一節中我們學習了當檔案已經載入到記憶體中的操作,那麼作業系統是如何在磁碟中尋找檔案並載入到記憶體中的呢?本節將講述這一內容。

一、磁碟

要了解檔案在沒有開啟的時候的儲存情況,我們就需要了解儲存它的硬體:磁碟。 在計算機中磁碟屬於外設範疇,它是計算機內部的一個機械裝置。 在這裡插入圖片描述 磁碟分為機械磁碟和固態磁碟,目前的筆記本上基本都裝載的是固態磁碟。 磁碟的基本單位是扇區,每一個扇區大概儲存512k的資料量。 但是我們理解磁碟時要把它想象成條形結構來理解。就是將圓形磁碟看成矩形。 在這裡插入圖片描述 同時,我們又對這個長條形的磁碟分為不同大小的區域,就是所謂的C盤,D盤,E盤。 在這裡插入圖片描述

大部分計算機是隻有一個磁碟的,只是將其分為不同的區域。 同時,由於每一個盤的空間較大,因此我們需要繼續劃分管理。 在這裡插入圖片描述 我們將D盤分為很多個組來進行管理,它的組頭有一個BootBlock這是和啟動有關的。 而每一個組我們還要進行劃分管理,我們: 在這裡插入圖片描述 其中SuperBlock是與檔案結構相關的和GroupDescriptorTable是與組相關的。不過這兩個都不是本文的重點。 本文的重點在於理解BlockBitmap,inodeBitmap,inodeTable和DataBlocks。

二、檔案屬性與資料的儲存

1.inodeTable與Datablocks

當我們儲存一個檔案的時候,我們不僅要儲存它的屬性資訊還要儲存它的資料資訊。其中InodeTable與Datablocks分別存放的就是檔案的屬性資訊和資料資訊。 在InodeTable中有很多小塊,每一個小塊就是一個inode。它存放的是一個檔案的屬性資訊。 在這裡插入圖片描述 在Datablocks中和inodeTable是類似的,它包含很多block單元,每一個block單元儲存一定大小的資訊: 在這裡插入圖片描述 作業系統在尋找檔案時是使用inode編號來進行查詢的,而不是通過檔名,檔名是使用者層才進行使用的。Linux系統真正標識一個檔案,是通過inode編號。每一個檔案都有一個inode編號。同時在inode中還會存放檔案相對應的block塊中的編號。 如果是目錄檔案,它存放在DataBlock中的內容是目錄中的檔名與inode的對映關係。

2.InodeBitmap與BlockBitmap

InodeBitmap和BlockBitmap存放的是,InodeTable和DataBlocks的點陣圖。其中位元位的位置表示的是編號,位元位的內容表示的是是否被佔用。 比如:在InodeBitmap中的數字為0000 1010,表示的就是0號位的inode沒有被佔用,而1號位的inode已經被佔用了。 Blockmap同理。

3.舉例

我們通過舉一個例子來理解以上的內容:

mkdir tmp cd tmp touch hello.c echo "hello bit" >hello.c cat hello.c rm hello.c

touch hello.c:在InodeBitmap中找到沒有被佔用的inode單元,把屬性的資訊存放進去。 echo "hello bit">hello.c:檢視BlockBitp中沒有使用的block單元,將其餘inode建立對映,並將檔案的內容存放進去。 cat hello.c:通過tmp的inode找到並檢視tmp的Datablock,找到與hello.c檔名形成對映關係的inode值,通過這個inode找到對應的hello.c檔案的Datablock,從而列印其中的內容。 rm hello.c:在tmp的DataBlock找到與檔名hello.c相對應的inode,只需要將inodeBitmap中的該inode位置的數字由1置為0即可。不需要對其的inodeTable與DataBlock進行操作。

這也就是為什麼檔案的刪除非常的快,因為沒有刪除屬性和資料,只是將是否有效刪掉了。而對比於windows系統的回收站,其實在回收站中的檔案並沒有被刪除掉,僅僅只是被換了一個目錄而已。當我們不小心刪除了檔案,最好的做法就是什麼都不做,避免內容被覆蓋掉。 同理,mv指令其實只是在移動檔名與inode的對映關係。

三、軟硬連結

在Linux系統下的軟硬連結,我們可以理解為快捷方式。 使用ln選項來建立軟硬連結:

ln -s//建立軟連結 ln //建立硬連結

在這裡插入圖片描述 這裡我們就建立了一個關於log.txt的軟連結log_s。 在這裡插入圖片描述 建立一個硬連結log_h。 在這裡插入圖片描述 如果是軟連結,軟連結的inode和檔案的inode是不同的。說明軟連結新建了一個檔案,它有自己的屬性資訊和資料塊(儲存的是所指檔案的路徑+檔名)。而硬連結的inode和原來檔案的inode是相同的,說明硬連結並沒有建立檔案,而是增加了目錄DataBlock中檔名和inode的對應關係。 前一個紅色框表示的是硬連結的個數,當我們建立硬連結時,硬連結和該檔案都變成了2。當該值為0的時候表示檔案被刪除。 當我們建立檔案的時候,該值為1,但是當我們建立一個目錄的時候,該值為2。 在這裡插入圖片描述 這是因為test目錄下的.也是該目錄的一個硬連結。當在該目錄下再建立一個目錄時,值為3,這是因為該目錄下的..也表示test目錄。

四、檔案的時間屬性

我們可以通過stat來檢視檔案的基本屬性,比如我們新建一個file.txt。並向其中寫入一定的內容。

stat file.txt

在這裡插入圖片描述 其中access,modify,change表示的就是檔案的三個時間屬性.

1.Access

Access表示的是檔案的最近一次被訪問時間,但是我們通過cat指令訪問檔案發現,檔案的access時間並沒有發生變化。 在這裡插入圖片描述 這是因為開啟檔案是一個高頻操作,為避免大量重複重新整理,在較新的Linux核心中,Access不會立即被重新整理,而是有一定的時間間隔OS才會自動更新時間。

2.Modify

Modify表示的是最近一次的修改時間,時間被實時更新。

echo "hello bit">>file.txt

在這裡插入圖片描述

3.change

最近一次修改檔案屬性的時間:

chomd u+x file.txt

在這裡插入圖片描述 注意,當修改檔案屬性的時候,Modify沒有發生變化。但是當修改檔案內容的時候,change有可能會發生變化。這是因為修改檔案內容一般都會修改檔案屬性,比如增加內容就會修改檔案的大小屬性。

4.Makefile判斷檔案更新的方式

mytest:test.c      gcc $^ -o [email protected]     .PHONY:clean     clean:      rm mytest

其中test.c為mytest所依賴的原始檔。當Makefile進行make的時候,會檢查mytest和test.c的Modify時間,正常來說肯定是test.c的Modify時間比mytest的更早(因為mytest是由test.c進行生成的)。如果我們更改了test.c中的內容,那麼test.c的Modify時間就會比mytest的晚,此時Makefile會執行相應的依賴方法。 我們還可以驗證一下:在沒改test.c的情況下進行touch(touch一個存在的檔案表示修改時間),此時就可以進行make了。 在這裡插入圖片描述

五、總結

我們使用整個檔案的建立,使用以及刪除來對檔案操作進行總結。

1.touch file.txt

建立檔案,首先作業系統在InodeBitmap和BlockBitmap分別找到不為1的數字,將其下標作為該檔案的Inode和block的編號。並將之置為1,其中Inode只有一個,block可以有多個。

2.echo "I am the king of Asgard">>file.txt

將呼叫echo程序,先將標準輸出關閉(close(1))在該程序中將file.txt檔案使用系統呼叫函式open開啟, 首先通過目錄檔案的Blocktable,找到file.txt與inode的對映。然後通過該對映找到file.txt這個檔案以及它的內容,並載入到記憶體中,形成file結構體成為該程序的一個檔案。 file.txt獲得一個檔案描述符,存放在該程序的files結構體中,該檔案描述符就是原來標準輸出的檔案描述符:1。 程序通過列印函式向檔案描述符為1的檔案中列印內容,此時就是在向file.txt中列印內容。

3.rm file.txt

將InodeBitmap中表示file.txt檔案的的數字1置為0。