文件管理(三)—— 文件目录

前言

文件目录即我们熟悉的"文件夹",其层级结构让用户可以清晰地组织和快速找到文件,也让操作系统能够根据路径名实现按名存取。本文从操作系统视角探讨目录的实现原理,依次介绍文件控制块、目录操作、四种目录结构,以及索引节点优化机制。

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 磁盘索引节点与内存索引节点

  • 磁盘索引节点:存储在外存,包含文件的全部静态属性
  • 内存索引节点:文件被访问时调入内存,在磁盘索引节点基础上额外增加动态信息(如是否被修改、当前有几个进程正在访问等)
相关推荐
码匠许师傅8 分钟前
【C++ 面试真题】聊聊 C++ 的关联容器
开发语言·c++·面试
黄敬峰9 分钟前
用 NestJS 实现待办事项接口:RESTful CRUD 与错误处理一次讲透
面试
蔓越莓20 分钟前
打包工具:编译器ESBuild
前端·面试
Escalating_xu42 分钟前
【Linux】进程信号:从产生、阻塞与递达到 sigaction、可重入与内核返回路径
linux·运维·面试·职场和发展
JL152 小时前
Java并发编程面试全攻略-从synchronized到AQS底层原理
java·开发语言·面试·并发编程
程序员爱钓鱼2 小时前
Go 编程实战:数组 Array——固定长度的数据集合
后端·面试·go
ShineWinsu10 小时前
对于C++:auto_ptr、unique_ptr、shared_ptr的模拟实现
c++·面试·笔试·智能指针·unique_ptr·shared_ptr·auto_ptr
黄敬峰13 小时前
一文搞懂 NestJS 后端框架:工厂模式、模块化与装饰器
面试
码匠许师傅14 小时前
【C++ 面试真题】聊聊 C++ 的多继承与虚继承
开发语言·c++·面试