下面分别详细解释您提到的三个问题:
“文件系统怎么定位文件”、“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 链接数和文件描述符都归零时,才真正回收。