文件管理(七)—— 文件系统的层次结构和布局

前言

本节从两个角度理解文件系统的结构:纵向 看各功能层次如何协同完成文件操作;横向看文件系统在外存和内存中的布局。

1. 文件系统的层次结构

文件系统从上至下分为以下几个层次,每一层负责不同的功能:

层次 主要职责 对应知识点
用户接口 向用户和应用程序提供系统调用接口(open/read/write/close 等),处理系统调用请求 文件的基本操作
文件目录系统 根据路径逐级查找目录,找到文件对应的 FCB;管理打开文件表、活跃目录表 文件目录
存取控制模块 验证用户对文件是否拥有所请求的操作权限 文件保护
逻辑文件系统与文件信息缓冲区 将记录号转换为逻辑地址;将索引表等文件信息缓冲到内存 文件逻辑结构
物理文件系统 将逻辑地址转换为实际物理地址 文件物理结构
辅助分配模块 管理磁盘存储空间,负责物理块的分配与回收 文件存储空间管理
设备管理模块 直接与磁盘硬件交互:分配设备、分配缓冲区、磁盘调度、启动/释放设备 磁盘管理

以"删除学生信息 Excel 表中最后 100 条记录"为例,各层次依次参与:

  1. 用户接口:接收用户发出的删除请求(系统调用)
  2. 文件目录系统:根据文件路径逐级查找目录,找到对应 FCB
  3. 存取控制模块:验证该用户是否有"删除记录"的权限
  4. 逻辑文件系统:将记录号转换为对应的逻辑地址(可能需要查询索引表)
  5. 物理文件系统:将逻辑地址转换为物理地址
  6. 设备管理模块:与磁盘交互,执行实际的数据删除操作
  7. 辅助分配模块:回收删除记录后释放的空闲磁盘块

2. 文件系统的全局结构

2.1 外存中的结构

磁盘从出厂到可用,需要经过两次格式化:

物理格式化(低级格式化)

将磁盘划分为一个个扇区,同时检测坏扇区并用备用扇区替换。坏扇区对操作系统透明------操作系统访问某扇区时,磁盘驱动器会在后台自动用备用扇区替代,操作系统感知不到坏扇区的存在。

逻辑格式化(高级格式化)

将磁盘划分为一个个分区(卷)(即 C 盘、D 盘等),分区信息由分区表记录。每个分区内可以建立独立的文件系统。

以 Unix 文件系统为例,逻辑格式化后一个分区内的布局:

css 复制代码
| 引导块 | 超级块 | 空闲空间管理(位视图等)| I 结点区 | 根目录 | 其他文件和目录数据 |
区域 说明
引导块 存放启动操作系统所需的引导程序
超级块 记录空闲盘块的组织信息(成组链接法),用于快速找到空闲磁盘块
空闲空间管理 如位视图(0 表示空闲,1 表示已分配),用于快速判断某一磁盘块是否空闲
I 结点区 连续存放所有文件的索引节点(inode),大小相同,可通过下标直接定位任意 inode
根目录 逻辑格式化完成后即建立,文件系统以根目录为起点组织所有文件
数据区 存放普通文件和目录的实际数据,逻辑格式化后为空,随文件创建逐步填充

超级块与位视图均可标记空闲块,但作用侧重不同:超级块侧重快速找到多个空闲块,位视图侧重快速判断某块是否空闲。

2.2 内存中的结构

文件系统在内存(内核区)中维护三个重要数据结构:

数据结构 数量 内容 作用
目录缓存 全局 近期访问过的目录文件数据 避免重复读磁盘,加快目录检索速度
系统打开文件表 全局唯一一张 所有正在被进程使用的文件的 FCB 副本及打开计数器 统一管理已打开的文件
进程打开文件表 每个进程一张(存于 PCB) 该进程已打开的文件、打开方式(读/写)、指向系统表的索引 记录进程的文件使用状态

2.3 打开并读取文件的完整流程(示例)

以 open("m/a") 后 read(fd, ...) 为例:

scss 复制代码
open("m/a")
  ↓
① 查找目录缓存,将目录 m 的数据读入内存
  ↓
② 在目录 m 中找到文件 a 的目录项(FCB)
  ↓
③ 将 FCB 复制到系统打开文件表,打开计数器置 1
  ↓
④ 在进程打开文件表中新建条目(记录打开方式 + 指向系统表的索引)
  ↓
⑤ 返回文件描述符 fd(进程打开文件表的索引号)

read(fd, buf, n)
  ↓
① 通过 fd 找到进程打开文件表中对应条目
  ↓
② 通过索引找到系统打开文件表中对应条目,获取 FCB
  ↓
③ 根据 FCB 确定文件在外存中的位置
  ↓
④ 将数据从外存读入内存 buf

文件描述符(fd) 本质上是进程打开文件表的索引号,也称"文件句柄"。打开文件后的所有读写操作只需传入 fd,无需再提供文件路径或文件名。

相关推荐
用户479492835691519 小时前
字节Agent开发技术分享—旧会话越聊越笨,新会话又得重讲?我给 Matt Pocock Skill 炼了套《影分身之术》:本体想清楚,分身写代码,完事回来汇报
面试·agent
蒸蒸yyyyzwd1 天前
cpp 选手准备秋招学习笔记 day10
笔记·面试·求职招聘
蔓越莓1 天前
Webpack 常用 Loader +手写Loader
前端·面试
蔓越莓1 天前
性能优化:webpack打包层面优化
前端·面试
面试鸭1 天前
Anthropic 让 Claude 接了 CI 值班的第一班,人剩下的是写规则和合 PR
后端·面试
码匠许师傅1 天前
【C++ 面试真题】19. 聊聊 C++ 的迭代器
开发语言·c++·面试
黄敬峰1 天前
TypeScript 工具类型一次讲透:Pick、Omit、Partial、Record 逐个击破
面试
码匠许师傅1 天前
【C++ 面试真题】20. 聊聊 C++ 的标准库常用算法
c++·算法·面试
一只叫煤球的猫1 天前
Spring AI 2.0 源码解析(二):Starter 如何自动装配 ChatClient ?
后端·面试·langchain
执行部之龙1 天前
AI 前端流式输出手写与扩展知识
前端·javascript·面试·agent