前言
文件目录即我们熟悉的"文件夹",其层级结构让用户可以清晰地组织和快速找到文件,也让操作系统能够根据路径名实现按名存取。本文从操作系统视角探讨目录的实现原理,依次介绍文件控制块、目录操作、四种目录结构,以及索引节点优化机制。
1. 文件目录
1.1 文件控制块(FCB)
目录在操作系统内部是一种有结构文件 ,由一条条目录项(FCB,文件控制块) 组成,每个目录项对应该目录下的一个文件或子目录。
FCB 中包含三类信息:
- 基本信息:文件名、物理地址(外存存放位置)、逻辑结构、物理结构等
- 存取控制信息:文件是否可读、是否可写等权限信息
- 使用信息:文件创建时间、最后修改时间等
其中文件名 和物理地址是最关键的两项------FCB 存在的核心作用就是建立从文件名到外存物理位置的映射,让用户通过文件名就能找到对应的数据。
一组 FCB 的有序集合 = 一个文件目录;
一个 FCB = 一个文件目录项;
每个文件对应一个唯一的 FCB。
1.2 目录的基本操作
| 操作 | 说明 |
|---|---|
| 搜索 | 按文件名在目录中查找对应目录项 |
| 创建文件 | 在所属目录中增加一条新的目录项 |
| 删除文件 | 删除文件数据的同时删除对应目录项 |
| 显示目录 | 列出目录下所有文件及其属性 |
| 修改目录 | 文件属性(如文件名)变化时同步修改目录项 |
2. 目录结构
2.1 单级目录结构
整个系统只维护一张目录表,每个文件占用一个目录项。
优点:实现简单,支持按名存取。
缺点:不允许文件重名------由于所有文件都在同一张目录表中,关键字(文件名)必须唯一,否则无法区分。创建新文件时需先检查是否重名,这使得单级目录不适用于多用户操作系统。
2.2 两级目录结构
将目录分为两级:主文件目录(MFD)和用户文件目录(UFD)。MFD 记录用户名及其对应 UFD 的存放位置,每个 UFD 存放该用户所有文件的 FCB。
优点:不同用户的文件允许重名(分属各自的 UFD);可通过验证用户名实现访问限制。
缺点:用户无法在自己的文件之间再进行分类,管理不够灵活。
2.3 树形目录结构(多级目录)
现代操作系统普遍采用的目录结构。每个目录下可以再有子目录,形成树状层次,不同目录下的文件允许重名。
当前目录与磁盘 I/O
从根目录按绝对路径查找文件时,每经过一级目录就需要一次磁盘 I/O(将该级目录文件调入内存)。若路径有 3 层,则需 3 次磁盘 I/O。
引入当前目录后,已打开的目录常驻内存,从当前目录出发只需读取剩余层级,显著减少磁盘 I/O 次数,提升文件访问效率。
优点:层次清晰,方便文件分类、管理与保护。
缺点 :不便于实现文件共享(树形结构中每个文件只有唯一路径)。
2.4 无环图目录结构
在树形目录的基础上,允许不同目录中的节点指向同一个文件或子目录,形成有向无环图(DAG),从而支持文件共享。
共享计数器
共享文件与复制文件不同:共享时多个用户指向同一份数据,任意一方的修改对所有共享者可见。
为了安全删除共享文件,每个共享节点维护一个共享计数器:
- 用户请求删除文件时,仅删除该用户的目录项,计数器减 1
- 只有计数器归零时,才真正删除文件的实际数据
不同用户可以用不同文件名指向同一个共享文件(如 user1 叫它
demo,user2 叫它mydemo)。
2.5 四种目录结构对比
| 目录结构 | 是否允许重名 | 是否支持文件共享 | 主要缺点 |
|---|---|---|---|
| 单级目录 | 不允许 | 不支持 | 不允许重名,不适合多用户 |
| 两级目录 | 不同用户可重名 | 有限制 | 用户无法对自己的文件分类 |
| 树形目录 | 不同目录可重名 | 不便 | 不便于文件共享 |
| 无环图目录 | 不同目录可重名 | 支持 | 需要共享计数器机制 |
3. 索引节点(inode)
索引节点是对 FCB 的优化,其动机来自于目录检索效率问题。
3.1 优化动机
在目录搜索过程中,操作系统只需要用到文件名来逐条匹配,文件的物理地址等信息在匹配成功之前完全用不到。然而传统 FCB 把所有信息都存在目录中,浪费了目录项空间,导致每个磁盘块能存放的目录项数量少,检索时磁盘 I/O 次数多。
量化示例:
- 若 FCB 大小为 64 字节,磁盘块大小 1 KB,则每块仅能存 16 个目录项
- 640 个目录项需 40 个磁盘块,平均检索需读 20 次磁盘
- 引入索引节点后,目录项仅含文件名(14 字节)+ 索引节点指针(2 字节)= 16 字节
- 每块可存 64 个目录项 ,640 个目录项仅需 10 个磁盘块,平均检索只需读 5 次磁盘
3.2 工作原理
采用索引节点后,目录项中只保留文件名 + 索引节点指针 ,其余所有信息(物理地址、文件类型、权限、时间戳等)都移入索引节点中独立存储。
ini
目录项: [文件名 | → 索引节点编号]
索引节点: [物理地址 | 文件类型 | 权限 | 大小 | 时间 | ...]
检索流程:按文件名在目录中搜索 → 找到匹配项得到索引节点编号 → 将索引节点调入内存 → 根据物理地址找到文件数据。
3.3 磁盘索引节点与内存索引节点
- 磁盘索引节点:存储在外存,包含文件的全部静态属性
- 内存索引节点:文件被访问时调入内存,在磁盘索引节点基础上额外增加动态信息(如是否被修改、当前有几个进程正在访问等)