我想要知道UNIX操做系統下close
和unlink
的區別,查閱了相關網絡資料和參考了《APUv3》寫下這篇記錄。html
我將從計算機磁盤分區開始寫起,一直UNIX操做系統的文件系統(主要指UFS:傳統的基於BSD的UNIX文件系統),而後辨明兩者區別。能夠直接跳至第三部分:《i結點和目錄項》查看。node
如下是本文的提綱:linux
open
和close
作了什麼?unlink
作了什麼?是否會刪除文件?硬盤在出廠時要進行一次「低級格式化」,低級格式化的做用是把硬盤劃分紅扇區(sector)。
一個扇區指一個磁道上面固定大小(通常是512字節)的弧段,是物理上的最小獨立單位,是硬件被OS使用的最小的操做單元,就是一個扇區一個扇區進行操做(扇區的大小在存儲設備生產時就設計好)。shell
硬盤最開頭(編號最小)的扇區叫作引導扇區(bootsector)。
計算機開機後訪問硬盤時所必須要讀取的這個扇區,用於加載計算機操做系統,並轉讓處理器控制權給操做系統,因此引導扇區是不會劃分給分區的。數組
引導扇區的512個字節中:網絡
剩下的66個字節裏面有:數據結構
塊(block)是邏輯上劃分的,一個塊由一個或多個扇區組成,是文件系統中的最小的操做單位(此處的「最小單位」,針對虛擬文件系統和具體文件系統分別指的是物理塊和邏輯塊)。oracle
塊能夠分爲物理塊和邏輯塊。函數
雖說是物理塊,它仍然是邏輯上劃分的。ui
操做系統的虛擬文件系統從硬件設備上讀取一個block,就是讀取了一個邏輯塊,實際是從硬件設備讀取一個或多個sector。
對於文件管理來講,每一個文件對應的多個block多是不連續的。block最終要映射到sector上,因此block的大小通常是sector的整數倍。
物理塊的大小是可變化的,這取決於你在建立文件系統時的選擇。好比說,建立文件系統時,設置N個扇區組成一個物理塊,那麼每次操做系統的虛擬文件系統的I/O操做就會讀取一個虛擬塊到內存中。
虛擬文件系統:Linux支持的具體文件系統有:
- 傳統文件系統:Ext二、ext三、ext四、Reiserfs(處理小文件)、Xfs、jfs
- 光盤文件系統:ISO9660
- 集羣文件系統:GFS(紅帽開發)、OCFS(oraclecluster fs)
- 網絡文件系統:NFS、CIFS
- Windows上的文件系統:VFAT(包括FAT、FAT32)、NTFS
- USB文件系統:vfat
Linux把這些具體文件系統的差別屏蔽掉,構建了一個統一的虛擬文件系統(virtual file system,VFS),在用戶和基本文件系統之中加入了一層VFS,故在用戶看來Linux的文件系統只有VFS。
邏輯塊是相對於物理塊而言的。邏輯塊與物理塊的關係相似於虛擬內存中的頁與物理內存中的頁面的關係。
具體文件系統管理的是一個邏輯空間,這個邏輯空間就象一個大的數組,數組的每一個元素就是 具體文件系統 操做的基本單位——邏輯塊。
邏輯塊是從0開始編號的,並且,邏輯塊是連續的。與邏輯塊相對的是物理塊,物理塊是數據在磁盤上的存取單位,也就是每進行一次I/O操做,最小傳輸的數據大小。
只在須要進行I/O操做時才進行邏輯塊到物理塊的映射,這顯然避免了大量的I/O操做,於是文件系統可以變得高效。邏輯塊做爲一個抽象的概念,它必然要映射到具體的物理塊上去,所以,邏輯塊的大小必須是物理塊大小的整數倍,通常說來,二者是同樣大的。
能夠把一個磁盤分紅多個分區。
計算機中最多能夠有4個主分區,可是咱們能夠在分區表(見第一部分的「引導扇區」)中拿出16字節,它不標識主分區,而是標識一個擴展分區。擴展分區能夠分紅N個邏輯分區。微軟通常這樣用,一個主分區(C盤),加一個擴展分區,由擴展分區再衍生出多個邏輯分區。Windows操做系統能夠裝在邏輯分區上。在這種狀況下計算機能夠有3個主分區,1個擴展分區。
擴展分區實際上 不是物理可用的分區,它僅僅是一個指向下一個分區的指針,這種指針結構將造成一個單向鏈表。
這樣在主引導扇區中除了主分區外, 僅須要存儲一個被稱爲擴展分區的分區數據,經過這個擴展分區的數據能夠找到下一個分區(實際上也就是下一個邏輯磁盤)的起始位置,以此起始位置類推能夠找到全部的分區。不管系統中創建多少個邏輯磁盤,在主引導扇區中經過一個擴展分區的參數就能夠逐個找到每個邏輯磁盤。
咱們在給新硬盤上創建分區時都要遵循如下的順序:創建主分區→創建擴展分區→創建邏輯分區→激活主分區→格式化全部分區
注意:
硬盤的容量=主分區的容量+擴展分區的容量
; 擴展分區的容量=各個邏輯分區的容量之和
。boot.ini
、ntldr
、ntdetect.com
等,必須放在引導分區中。每一個分區上能夠包含一個文件系統。
UNIX文件系統包括引導塊、超級塊、i節點區、文件存儲區(數據區)、進程對換區等。
引導塊
佔用第0號物理塊,不屬於文件系統管轄。若是系統中有多個文件系統,只有根文件系統纔有引導程序放在引導塊中,其他文件系統都不使用引導塊。超級塊
佔用第1號物理塊,是文件系統的控制塊,超級塊包括:文件系統的大小、空閒塊數目、空閒塊索引表、空閒i節點數目、空閒i節點索引表、封鎖標記等。超級塊是文件系統爲文件分配存儲空間、回收存儲空間的依據。i節點區
存放i節點,i節點是對文件進行控制和管理的一種數據結構。文件存儲區
是存放文件內容的區域,文件存儲區中各數據塊的使用狀況在超級塊中有記錄,系統利用超級塊中的記錄完成對數據塊的分配和回收。每個文件都由本身的i節點,每一個i節點都有惟一的i節點號。i結點保存了文件的屬性和類型、存放文件內容的物理塊地址、最近一次的存取時間、最後一次修改時間、建立此文件的時間。
i節點的結構以下(參考/usr/include/sys/ino.h
)
struct dinode { ushort di_mode; short di_nlink; ushort di_uid; ushort di_gid; off_t di_size; char di_addr[40]; time_t di_atime; time_t di_mtime; time_t di_ctime; }
從上面的結構中能夠看出i節點中沒有記錄文件名字的。
事實上當咱們根據文件名查找文件時
顯然,在不一樣的目錄中,不一樣(或相同)的文件名能夠映射爲同一個i結點的編號,這意味着不一樣的文件名實際上能夠引用自同一個文件內容。
在i結點結構體定義中能夠找到short di_nlink;
項,它就是連接計數,有多少個目錄項指向這個i結點,那麼它的di_nlink
就是多少。和Java中的垃圾回收機制同樣,若是一個文件沒有任何目錄項引用它,即該文件不可能再被索引到,此時di_nlink==0
這意味着文件能夠被刪除(也就是釋放文件內容所佔用的磁盤數據塊)。
這就是爲何「解除對一個文件的連接」不總意味着「釋放文件佔用的磁盤塊」,由於連接計數不爲0,說明還有其餘的目錄項引用了該文件。
這也是爲何刪除文件是unlink
而不是'delete
,由於沒有任何目錄項連接到該文件時,操做系統會自動釋放該文件所佔用的數據塊。
這種連接,就稱爲「硬連接」。
硬連接就是讓多個不在或者同在一個目錄下的文件名, 同時可以修改同一個文件,其中一個修改後,全部與其有硬連接的文件都一塊兒修改了。
值得一提的是目錄連接
一個目錄也能夠看做是一個文件,也就是說,目錄名映射爲一個i結點號,i節點號指向一個i結點,這個i結點有指針指向一個目錄數據塊,而這個目錄數據塊中就是目錄項數據,例如(文件名,i結點編號)
或(子目錄名,i結點編號)
等記錄。
注意,子目錄中由於有指向父目錄的項(即..
),所以父目錄中的每個子目錄都會使父目錄連接計數加1。
符號連接(軟連接)是一類特殊的文件, 其包含有一條以絕對路徑或者相對路徑的形式指向其它文件或者目錄的引用。對符號連接文件進行讀寫的程序會表現得直接對目標文件進行操做。
也就是說,符號連接文件內容是目標文件的一個路徑,對符號連接文件操做,都會按照其中的路徑找到真正的目標文件,而後將操做施加上去。
一個符號連接文件僅包含有一個文本字符串,其被操做系統解釋爲一條指向另外一個文件或者目錄的路徑。
它是一個獨立文件,其存在並 不依賴於目標文件。
若是刪除一個符號連接,它指向的目標文件不受影響。
若是目標文件被移動、重命名或者刪除,任何指向它的符號連接仍然存在,可是它們將會指向一個不復存在的文件。這種狀況被有時被稱爲 被遺棄。
open
、close
、unlink
對連接數的影響每個文件,均可以經過一個struct stat
的結構體來得到文件信息,其中一個成員st_nlink
表明文件的連接數。
touch
命令,或者在程序中open
一個帶有O_CREAT
的不存在的文件時,文件的連接數爲1。open
一個已存在的文件不會影響文件的連接數。open
的做用只是使調用進程與文件之間創建一種 訪問關係 ,即open
以後返回fd
,調用進程能夠經過fd
來read
、write
等等一系列對文件的操做。close()
就是 消除 這種調用進程與文件之間的訪問關係。天然,不會影響文件的連接數。close
時,內核會檢查打開該文件的進程數,若是此數爲0(沒有任何進程使用該文件),進一步檢查文件的連接數,若是這個數也爲0,那麼就刪除文件內容。link
函數建立一個新目錄項,而且 增長一個連接數 。unlink
函數 刪除目錄項 ,而且 減小一個連接數。若是連接數達到0而且沒有任何進程打開該文件,該文件內容才被真正刪除。unlilnk
以前沒有close
,那麼依舊能夠訪問文件內容。(也就是連接數爲0,可是仍然有進程在訪問。能夠想到此時若是close
後,根據第4條,文件就會被真正刪除。)綜上所訴:
link
、unlink
以及open
的建立。unlink
。close
可以實施刪除文件內容的操做,則一定是由於在close
以前有一個unlink
操做。