下面分別詳細解釋您提到的三個問題:
“文件系統怎么定位文件”、“inode 是什么”、“為什么刪除后還可能被占用”。
一、文件系統怎么定位文件
1.1 目錄與文件名并不直接存儲文件數據
在常見的 Unix/Linux 文件系統(如 ext4、xfs)或類似的文件系統中,目錄(Directory) 只記錄文件名與一個索引指針(例如 inode 號)的對應關系。
-
當你通過路徑(如
/home/user/test.txt
)查找文件時,操作系統會先從根目錄開始,根據每一級文件名,讀取相應目錄文件里的條目,然后找到該文件對應的索引(如 inode號)。 -
一旦獲得 inode,操作系統才能進一步定位到文件真正的數據塊。
1.2 inode 與數據塊
-
每個文件都有一個 inode(在類 Unix 文件系統中),包含它的數據塊指針、文件大小、權限、所有者等元數據。
-
文件系統通過 inode 查找到物理磁盤上的若干塊(blocks),其中存放著文件內容。
-
所以從目錄 → inode → 數據塊就完成了文件的定位。
1.3 簡化步驟
-
用戶輸入文件路徑。
-
操作系統逐級進入目錄:
-
從根目錄 inode(固定位置)開始,找到
/home
目錄; -
打開
/home
目錄文件,找到user
子目錄; -
再打開
user
目錄文件,找到test.txt
的目錄項; -
讀到一個 inode 號,例如 12345。
-
-
讀取 inode 號 12345,獲取對應的數據塊指針數組;
-
根據數據塊指針,到磁盤上把這些 block 一一讀出來,拼接成文件內容返回給應用程序。
二、inode 是什么?
2.1 inode 的定義
-
inode(索引節點) 是類 Unix 文件系統中的一種數據結構,用于存儲文件的元信息(metadata)。
-
典型包含:
-
文件大小、訪問權限(rwx)、文件所有者(UID/GID)、時間戳(修改時間、訪問時間等);
-
數據塊指針(block pointers),告訴操作系統文件內容在哪些磁盤塊上。
-
2.2 inode 不存儲文件名
-
在 Unix-like 文件系統中,inode 不記錄文件名。文件名只保存在目錄里,用來映射 “文件名 → inode號”。
-
一個 inode 可能對應多個文件名(硬鏈接),也可能當前沒有任何目錄項引用它(此時如果仍有進程打開它,就還在占用;如果無進程也無目錄項,就會被回收)。
2.3 inode 是如何組織數據塊的?
-
inode 內部會有一些“直接塊指針”、“間接塊指針”等結構:
-
前若干個指針直接指向數據塊;
-
當文件過大,直接塊不夠用,還會用“一級間接塊”、“二級間接塊”,間接塊里又存更多數據塊指針;
-
這樣就能索引到更大范圍的磁盤空間。
-
三、為什么刪除后還可能被占用?
3.1 “刪除文件”在 Unix-like 的含義
-
當你執行
rm file
或調用系統調用unlink(file)
,系統會刪除目錄項(即“文件名 → inode 號”的映射)并將 inode 的鏈接數減1。 -
如果鏈接數變為 0,說明沒有任何目錄項再指向這個 inode。
-
但如果還有進程打開這個文件,內核會維持一個打開文件描述符的計數;只要描述符沒關閉,對應 inode 和數據塊不會釋放。
3.2 已刪除但仍被進程使用
-
某些場景下,一個進程在打開文件后,你去刪除該文件的名字,該進程仍可以正常讀寫——因為它仍然有一個“打開文件句柄”指向這個 inode。
-
文件系統不會真正回收 inode 和數據塊,直到最后一個進程關閉該文件描述符。
-
這就是為什么“文件被刪”但磁盤空間依舊被占用,直到沒有任何進程再用它,就可見到空間被釋放。
3.3 常見案例
-
日志文件:一個服務進程正在寫日志,管理員刪除了日志文件卻發現磁盤空間沒變小;實際上這時文件名沒了,但后臺進程還持有打開句柄,一直寫到已刪文件里。只有服務重啟或關閉文件后,空間才真正釋放。
四、總結
-
文件系統怎么定位文件?
-
通過目錄文件找到對應的 inode 號,再由 inode 查到磁盤上真正的數據塊。
-
-
inode 是什么?
-
是存儲文件元數據和數據塊指針的結構體,不記錄文件名;名稱保存在目錄項里。
-
-
為什么刪除后可能還被占用?
-
因為在 Unix-like 下,刪除操作主要是“移除文件名 → inode 映射”。只要進程還有文件描述符指向這個 inode,inode 就不會被釋放;文件的數據塊也不釋放,直到最后一個打開它的進程關閉該文件。
-
如此便能理解:文件系統刪除一個文件名,不見得立刻把磁盤空間歸還系統;只有當 inode 鏈接數和文件描述符都歸零時,才真正回收。