第4章 文件管理
第4章 文件管理¶
本章概念较多、逻辑环环相扣。重点:文件系统的结构与实现、文件分配、空闲空间管理、FCB、索引结构、树形目录、文件共享、文件系统布局、虚拟文件系统。 ⚠️ 教材提醒:多数考生对进程与内存管理掌握较好,但文件与 I/O 管理往往基础薄弱,甚至在基本问题上失分。
b_263_6【知识树】第4章骨架¶
- 文件系统基础
- 文件定义与属性(元数据)、分类
- 文件系统四层结构
- 逻辑结构:无结构(流式)/ 有结构(顺序、索引、索引顺序、直接)
- 目录与文件
- FCB 与索引节点 inode
- 目录结构:单级 / 两级 / 树形 / 无环图
- 文件操作:创建、删除、打开、关闭、读、写
- 文件共享:硬链接 vs 软链接
- 文件保护:访问类型、访问控制、口令、加密
- 文件的物理结构:连续 / 链接(隐式、显式FAT)/ 索引(多级、混合)
- 文件系统实现
- 文件系统布局(外存结构 + 内存结构)
- 外存空闲空间管理:空闲表、空闲链表、位示图、成组链接
- 虚拟文件系统 VFS、文件系统挂载
💡 贯通整章的一条访问链:路径名逐级查目录 → 定位 inode/vnode → open 建立 fd 与打开文件对象 → 字节偏移换算为文件逻辑块 → 按连续/链接/索引结构找到物理块 → 先查内核缓存 → 未命中才经块层、调度、驱动和 DMA 访问设备。做综合题时沿这条链逐层回答,避免把目录、打开表、分配方式和 I/O 混在一起。
b_263_04.1 文件系统基础¶
文件由哪三层数据组成?¶
自底向上: - 数据项:最低级的数据组织形式 —— 基本数据项(描述某一方面属性的一个值,数据中的最小逻辑单位)、组合数据项(由多个基本数据项组成) - 记录:一组相关数据项的集合,描述一个对象某方面的完整属性 - 文件:由创建者定义的、具有文件名的一组相关元素的集合
⚠️ 有结构文件由若干格式相似的记录组成;无结构文件被视为一个连续的字节流。 ⚠️ 教材说明:操作系统对文件并无严格统一的定义;基本访问单元可以是字节或记录。
b_264_0文件的八个属性(元数据)?¶
- 名称:⚠️ 同一目录中必须唯一
- 类型、创建者(创建该文件的用户 ID)、所有者(⚠️ 通常有权修改文件属性或访问权限)
- 位置:指向文件在外存设备上物理存储位置的指针
- 大小、保护(读/写、执行等权限)
- 创建时间、最后修改时间、最后访问时间(用于审计、备份或缓存管理)
💡 文件属性 = 文件元数据,用于支持管理、保护与检索。
b_264_12文件的四种分类方式?¶
- 按性质和用途:系统文件、用户文件、库文件
- 按数据形式:源文件、目标文件(编译中间文件)、可执行文件
- 按存取控制属性:只读文件、读/写文件、可执行文件
- 按组织形式与处理方式:普通文件、目录文件、特殊文件(如设备文件)
b_265_0文件系统的四个层次?¶
- I/O 控制:设备驱动程序 + 中断处理程序,负责内存与磁盘之间传输数据;⚠️ 把高层命令转换为底层硬件指令
- 基本文件系统:向驱动程序发通用命令读写物理块(每个物理块由唯一的磁盘地址标识);⚠️ 管理内存缓冲区
- 文件组织模块:⚠️ 建立文件逻辑块与物理块之间的映射(逻辑块从 0 到 N 顺序编号,通常与物理布局不一致);⚠️ 还包含空闲空间管理器
- 逻辑文件系统:管理元数据(文件名、目录项、权限、时间戳),⚠️ 不含实际数据内容;维护目录结构、通过 FCB 记录属性、实现文件保护
💡 记忆法:"驱动 → 读块 → 映射 → 管名字和权限",从下到上。
b_265_3;PDF 第 265 页 · b_265_10逻辑结构和物理结构的区别?¶
- 逻辑结构:用户视角所看到的文件组织形式;⚠️ 与底层存储介质无关
- 物理结构(存储结构):文件在外存上的实际存储方式;⚠️ 对用户透明
b_265_11;PDF 第 265 页 · b_265_12无结构文件为什么效率低?¶
无结构文件(流式文件):由连续的字符流构成,长度以字节为单位,通过读/写指针定位下一个要操作的字节。
典型用途:源程序、可执行文件、库函数。
⚠️ 缺点:缺乏显式的记录边界,检索特定内容只能顺序查找 → 不适用于频繁随机访问或按记录检索的场景。
b_266_0;PDF 第 266 页 · b_266_1定长记录和变长记录的差别在哪?¶
- 定长记录:所有记录长度相同,各数据项位置固定 → ⚠️ 可通过偏移量直接定位任意记录,支持高效随机访问
- 变长记录:⚠️ 无法直接计算记录位置,检索时通常只能顺序查找
有结构文件按记录组织形式分为:顺序文件、索引文件、索引顺序文件(另有直接文件/散列文件)。
b_266_2;PDF 第 266 页 · b_266_3顺序文件的两种结构和优劣?¶
- 串结构:按存入时间先后排列,不按键字排序 → ⚠️ 必须从头顺序扫描,效率低
- 顺序结构:按键字有序排列 → ⚠️ 定长且有序时可用偏移量直接定位,并支持折半查找
⚠️ 两个必背结论: - 批量处理场景下顺序文件的 I/O 效率在所有逻辑文件类型中最高(记录连续存储、访问局部性强) - ⚠️ 对于顺序存储设备(如磁带),顺序文件是唯一能有效工作的组织形式
缺点:频繁查找、修改、插入、删除单条记录时性能明显不足。
b_266_4;PDF 第 266 页 · b_266_5变长记录的地址怎么算?索引文件解决了什么?¶
- 定长记录:A_i = i × L(L 为记录长度)→ 直接算
- 变长记录:⚠️ A_i = 前 i−1 条记录长度之和 + 1 → 必须从头依次累加,效率低
索引文件的做法:为每个记录建一个索引项(含指向该记录的指针及其长度),按关键字排序。 ⚠️ 本质:索引表由定长记录构成,支持随机访问 → 把"对变长记录的顺序查找"转变为"对定长索引的随机查找"。
⚠️ 代价:需额外维护索引表,且每个记录对应一个索引项,存储开销大。
b_266_4;PDF 第 266 页 · b_266_8索引顺序文件的分组数取多少最优?¶
做法:把变长记录顺序文件分成若干组,为每组的首条记录建一个索引项(含关键字和指针),索引表按关键字有序。 ⚠️ 组内可无序,但组间必须按键字有序。
查找次数推导(N 条记录分 m 组,每组 s = N/m): - 索引表顺序查找平均 m/2 次 - 组内顺序查找平均 s/2 次 - 总平均 m/2 + (N/m)/2
⚠️ 当 m = √N 时该值最小,效率最优。(对比普通顺序文件平均 N/2 次。)
💡 这正是分块查找(索引顺序查找)的思想;记录极多时还可用两级或多级索引。
b_267_1;PDF 第 267 页 · b_267_2直接文件(散列文件)的优缺点?¶
记录的物理地址由其关键字经散列函数计算直接确定 → ⚠️ 支持极快的随机存取;缺点是不同关键字可能映射到同一地址,引发冲突。
💡 教材点题:有结构文件的各类逻辑组织方式(顺序、索引、索引顺序、散列),本质上都是围绕"如何高效查找数据"设计的。
b_267_104.2 目录与文件¶
目录管理的四个要求?¶
- 实现按名存取:⚠️ 用户仅需提供文件名,系统即可自动定位其在外存中的位置
- 提高检索速度
- 支持文件共享
- 允许文件重名:⚠️ 不同用户可对各自的文件使用相同名称
💡 文件目录是一种数据结构,记录每个文件的属性、存储位置等元数据。
b_269_5FCB 里存哪三类信息? ★1考¶
FCB(文件控制块)= 存放控制文件所需各种信息的数据结构,用于实现按名存取。 ⚠️ 每个文件对应一个 FCB,所有 FCB 的集合构成文件目录(目录文件)。
三类信息: - 基本信息:文件名、物理位置、逻辑结构、物理结构 - 存取控制信息:文件主、核准用户、一般用户的访问权限 - 使用信息:创建时间、最后修改时间
★ 考过 2009
b_269_10为什么要把文件名和描述信息分离? ★2考¶
⚠️ 问题:文件数量庞大时传统 FCB 目录占用大量磁盘空间;查找时要逐块读入目录项逐一比对文件名,⚠️ 而只有匹配成功时才需要物理地址 —— 检索阶段除文件名外的信息根本不必调入内存。
UNIX 的做法:把描述信息独立组织为索引节点(inode),⚠️ 目录项仅由"文件名 + 索引节点号"构成。
★ 考过 2020、2022
b_269_20inode 让查找快了多少?(经典计算) ★2考¶
教材算例: - 传统 FCB:FCB 占 64B,盘块 1KB → 每块容纳 16 个 FCB;目录共 640 个 FCB → ⚠️ 平均需启动磁盘 20 次(640/16 = 40 块,平均查一半 = 20) - UNIX 目录项:仅占 16B(14B 文件名 + 2B 索引节点号) → 每块容纳 64 个目录项 → ⚠️ 平均磁盘启动次数降至原来的 1/4(即 5 次)
💡 解题套路:每块目录项数 = 块大小 ÷ 目录项大小;平均启动次数 = 总块数 ÷ 2。
★ 考过 2018、2020
b_270_3磁盘索引节点存什么?¶
- 文件主标识符、文件类型(普通/目录/特殊文件)、文件存取权限
- ⚠️ 文件物理地址:通过 13 个地址项以直接或间接方式记录数据所在盘块编号
- 文件长度(以字节为单位)
- ⚠️ 文件链接计数:统计本文件系统中指向该文件的目录项(硬链接)数量
- 文件存取时间:最近访问、最近修改、索引节点最近被修改的时间
💡 每个文件有唯一的磁盘索引节点,是文件的"永久档案"。
b_270_6;PDF 第 270 页 · b_270_7内存索引节点比磁盘的多了什么?¶
文件被打开时把磁盘索引节点载入内存,额外新增五项运行时状态: - 索引节点号:在内存中唯一标识该节点 - 状态:是否被上锁或已修改,便于缓存一致性管理 - ⚠️ 访问计数:进程每访问一次加 1,结束减 1 —— 用于判断节点是否可释放 - 逻辑设备号:⚠️ 在多文件系统环境中尤为关键 - 链接指针:分别指向空闲链表与散列队列
b_270_9单级目录结构的三个缺点?¶
整个文件系统仅维护一张全局目录表,每个文件一个目录项。 - 创建:⚠️ 先遍历整张目录表确保无同名文件,再新增 FCB - 访问:按文件名查 FCB,合法性检查后执行操作 - 删除:定位 FCB → 回收存储空间 → 清除 FCB
三个缺点:⚠️ 查找效率低、不允许文件重名、难以支持文件共享 → 仅适用于早期单用户的简单文件系统。
b_270_13;PDF 第 270 页 · b_270_16两级目录结构解决了什么?还差什么?¶
分为主文件目录 MFD 和用户文件目录 UFD: - MFD 的每个目录项记录一个用户名及其 UFD 的存储位置 - UFD 包含该用户所有文件的 FCB;⚠️ 用户访问时只需在自己的 UFD 中查找
解决了:不同用户间文件重名的问题;隔离用户命名空间增强安全性;支持基于目录的访问控制。 ⚠️ 仍不足:每个用户仅有一个扁平的 UFD,无法对文件分类管理。
b_271_2;PDF 第 271 页 · b_271_5绝对路径和相对路径的区别? ★1考¶
- 绝对路径:从根目录开始;⚠️ 一条目录项路径可唯一定位一次查找结果,但同一文件对象可因硬链接拥有多条绝对路径(如多个目录项指向同一 inode)
- 相对路径:从当前目录(工作目录)出发;⚠️ 符号"."表示当前工作目录
⚠️ 为什么要设当前目录:目录层次较深时,每次从根目录逐级查找会耗费大量时间。 ⚠️ 每个用户都有专属的当前目录,登录后系统自动切换到该默认目录;Linux 的 /etc/passwd 记录各用户登录时的默认当前目录,cd 命令动态更新当前目录。
★ 考过 2010
⚠️ 校订/边界:“路径写法唯一”不等于“文件对象只有一条路径”;硬链接是最直接的反例。
b_271_10树形目录的优点和唯一缺点?¶
优点:支持灵活的文件分类、层次清晰、便于管理与保护;不同性质或归属的文件可分布于不同分支,并能针对各节点设置独立的存取权限。
⚠️ 唯一缺点:查找一个文件需按路径名逐级访问中间目录节点,导致磁盘 I/O 次数增加。
💡 UNIX、Linux、Windows 等绝大多数现代操作系统都采用树形目录结构。
b_271_8;PDF 第 271 页 · b_271_11无环图目录怎么处理共享节点的删除?¶
在树形目录基础上引入指向同一节点的有向边 → 同一个文件或子目录可出现在多个目录中。
⚠️ 删除的复杂性:直接物理删除会让其他共享用户访问失败。做法是为每个共享节点维护一个共享计数器: - 新增共享链时加 1,收到删除请求时减 1 - ⚠️ 仅当计数器归零才真正删除;否则只断开请求用户的共享链
⚠️ 代价:需额外维护引用计数等共享状态,管理开销增加。
b_272_3;PDF 第 272 页 · b_272_7目录的八种操作?¶
- 搜索:可从根目录或当前工作目录出发,支持精确匹配或部分文件名
- 创建文件:⚠️ 先检查是否重名,再新增目录项并初始化属性
- 删除文件:移除目录项,回收数据块及元数据
- 创建目录、删除目录(⚠️ 非空时两种策略:要求用户先手动清空;或系统自动递归删除)
- 移动目录:⚠️ 原目录项被转移,完整路径名自动更新,而文件内容保持不变
- 显示目录、改变目录(⚠️ 未指定时通常默认返回用户的主目录)
b_272_9目录实现的两种方法?¶
- 线性列表:由文件名 + 数据块指针组成;⚠️ 删除后重用目录项的三种策略:标记为未使用、加入空闲链表、把末尾项移到空位并缩短目录长度
- 优点实现简单;⚠️ 缺点查找效率低,目录越大扫描开销越高
- 哈希表:按文件名算哈希值索引;⚠️ 查找、插入、删除性能都很高,但必须处理哈希冲突
⚠️ 通用优化:把当前活跃的目录缓存到内存,减少磁盘 I/O。
b_273_1;PDF 第 273 页 · b_273_24.2.6 文件的物理结构¶
文件分配方式和空闲空间管理有什么分工? ★4考¶
- 文件分配方式:如何为文件分配已使用的磁盘块 → 对非空闲块的管理
- 文件存储空间管理:如何跟踪和分配空闲磁盘块 → 对空闲块的管理
三种分配策略:连续分配、链接分配、索引分配。
💡 教材类比:逻辑结构 vs 物理结构,就像数据结构里的"线性表"(逻辑)与"顺序表/链表"(物理实现) —— 逻辑结构描述"是什么",物理结构说明"如何存"。 ⚠️ 磁盘划分为若干磁盘块,文件系统通常按块组织 I/O。磁盘块与内存页面是不同层次的单位:实现可为效率把它们设成相同或整数倍,也可以不同,由缓存/I/O 层负责桥接。
⚠️ 校订/边界:“文件系统块”和“内存页”概念独立,不能把大小相等当成定义。
★ 考过 2009、2011、2013、2020
b_273_11连续分配的两优三缺? ★3考¶
每个文件占一组连续的块;目录项记录起始块号 + 总块数。⚠️ 若从块 b 开始占 n 块,访问第 i 块直接算 b + i − 1。
优点: - 既支持顺序访问,也支持直接访问 - ⚠️ 顺序访问效率最高 —— 文件块位于一条或少数几条相邻磁道上,磁头移动距离最小,寻道次数和寻道时间最小
缺点: - ⚠️ 易产生大量外部碎片 - ⚠️ 需要预先知道文件长度,难以支持动态增长(强行扩展可能覆盖相邻文件) - ⚠️ 删除或插入记录时往往需要物理移动后续记录
★ 考过 2011、2012、2014
b_273_15隐式链接的三个缺点? ★1考¶
目录项含指向第一块和最后一块的指针;⚠️ 除最后一块外每个盘块都存有指向下一块的指针,这些指针对用户完全透明。
链接分配的共同优点:消除外部碎片、支持动态分配无须预知文件大小、插入删除修改方便。
隐式链接的三个缺点: - ⚠️ 仅支持顺序访问 —— 访问第 i 块必须从首块依次遍历 - ⚠️ 可靠性差 —— 任一指针损坏则整个链断开 - 每个盘块要存指针,占用存储空间
★ 考过 2014
b_274_6引入"簇"有什么好处和代价? ★2考¶
簇 = 若干连续盘块组合成的基本分配单位,分配与链接均以簇为单位。
好处:指针数量大幅减少 → 降低存储开销 + 缩短链式查找时间 → 提升 I/O 性能。 ⚠️ 代价:可能产生内部碎片 —— 文件大小不是簇的整数倍时,最后一个簇的剩余空间无法被其他文件利用。
★ 考过 2017、2018
b_275_1FAT 表是什么?为什么能管空闲块? ★2考¶
显式链接把分散在各数据块中的指针集中存放在一张全局表里,⚠️ 整个文件系统通常设一张,称为文件分配表 FAT。FAT 的持久副本在磁盘上,运行时通常整体或部分缓存到内存。 - ⚠️ FAT 的表项与所有磁盘块一一对应 - 目录项只需记录起始块号,后续块号依次查 FAT 获得 - ⚠️ 用 −1 标记文件的最后一块,用 −2 表示该盘块空闲
💡 关键推论:FAT 不仅记录链式结构,还标识空闲盘块 —— 分配时只需在 FAT 中找值为 −2 的表项。
优点:既支持顺序访问,也比隐式链接更便于随机定位;若 FAT 已缓存,跟踪第 i 簇时只需在内存中沿 FAT 表项链前进,无须逐个读取前面的数据块。 缺点:⚠️ 逻辑上仍要沿 FAT 链跟踪前驱表项,并非 O(1) 直接算出第 i 簇;FAT 越大,缓存所需内存越多。
⚠️ 校订/边界:不能把“无需读取前 i−1 个数据块”写成“完全无需遍历前 i−1 个 FAT 表项”。
★ 考过 2019、2025
b_275_7单级索引分配的优缺点和容量计算? ★1考¶
为每个文件分配一个索引块(索引表),记录该文件的所有盘块号。
容量计算:盘块 4KB、盘块号 4B → 一个索引块容纳 4KB/4B = 1024 个盘块号 → 最大文件 1024 × 4KB = 4MB。
优点:支持高效的直接访问(读索引块第 i 项即得盘块号);不产生外部碎片。 缺点:⚠️ 每个文件都必须配一个索引块 —— 小文件时索引块利用率极低;大文件时超出单个索引块容量,虽可用链式指针链接多个索引块,但效率低下。
★ 考过 2012
b_275_12二级索引的容量和代价?¶
为索引块再建一级索引,称为主索引 —— 主索引表存放各二级索引块的盘块号。 💡 设计思想与内存管理中的多级页表高度相似。
容量:1024 × 1024 × 4KB = 4GB。
优点:显著提升大型文件的可扩展性与查找效率。 ⚠️ 缺点:磁盘 I/O 次数随索引级数增加而增多 —— 若只用多级索引,即使访问大量小文件的单个盘块也需多次磁盘 I/O。
b_276_3混合索引为什么要分小中大文件? ★1考¶
根据文件大小动态选用最合适的分配策略,在空间开销与访问性能之间取得最佳平衡: - 小文件:盘块地址全部直接存放在 inode 中 → 直接寻址,无须额外读索引结构 - 中型文件:单级索引 → 一次间址 - 大型/特大型文件:两级、三级索引
⚠️ UNIX 的索引节点共设 13 个地址项:i.addr(0) ~ i.addr(12)。
💡 偏移量题四步法:① 用 字节偏移 ÷ 盘块大小 得文件逻辑块号;② 依次扣除直接块、一次间址、二次间址的覆盖量,判断落在哪一档;③ 沿对应索引层找到数据块;④ 再按题设判断 inode、索引块、数据块是否已缓存,计算实际访盘次数。文件逻辑块号是否从 0 开始,以题设为准。
★ 考过 2013
b_277_1UNIX 混合索引的四档容量怎么算? ★6考¶
盘块 4KB、每个索引块容纳 1024 个盘块号: - 10 个直接地址项(i.addr(0)~i.addr(9))→ 10 × 4KB = 40KB - 一次间接地址(i.addr(10))→ 1K × 4KB = 4MB → 累计 4MB + 40KB - 二次间接地址(i.addr(11))→ 1K × 1K × 4KB = 4GB → 累计 4GB + 4MB + 40KB - 三次间接地址(i.addr(12))→ 1K×1K×1K×4KB = 4TB → 累计 4TB + 4GB + 4MB + 40KB
💡 记忆链:40KB → 4MB → 4GB → 4TB,每级乘 1024。
★ 考过 2010、2015、2018、2022
b_277_54.2.7 文件的操作¶
创建文件的六个步骤? ★1考¶
- ① 合法性与权限校验:文件名是否合法、是否重名、用户对目标目录是否有写权限
- ② 分配索引节点:从空闲 inode 池取一个,初始化元数据并标记为已占用
- ③ 分配磁盘块:按预估大小分配,块地址记录在 inode 中
- ④ 在目录中新建目录项,格式 <文件名, 索引节点号>
- ⑤ 更新文件系统元数据:空闲 inode 表、空闲磁盘块结构、目录大小、修改时间
- ⑥ (可选)打开并返回文件描述符
★ 考过 2025
b_278_5删除文件时什么情况下才真正回收? ★2考¶
- ① 路径解析与定位,验证对文件所在目录的写权限
- ② ⚠️ 检查使用状态与硬链接计数:文件正被打开 → 部分系统延迟物理删除;硬链接计数 > 1 → 仅删除当前目录项并把计数减 1,不回收 inode 与磁盘块;仅当计数为 1 时才执行完整删除
- ③ 移除目录项(用户视角下"消失",完成逻辑删除)
- ④ 释放索引节点(计数降至 0 时标记为空闲)
- ⑤ 释放磁盘块(数据块和索引块归还)
- ⑥ 释放内存临时资源
- ⑦ 更新文件系统元数据
★ 考过 2013、2021
b_278_8两级打开文件表分别存什么? ★3考¶
- 进程打开文件表(fd 表):⚠️ 每个进程独有,保存文件描述符、描述符级标志及指向打开文件对象的引用
- 系统打开文件对象(打开文件描述):保存本次打开的当前偏移、打开模式/状态、引用计数,并指向 inode/vnode
- inode/vnode:保存文件大小、权限、时间、磁盘位置等元数据,不保存某次打开私有的当前偏移
⚠️ 校订/边界:王道在不同位置采用了简化二层表述,读写指针归属看似前后不一。做概念题按题图字段作答;理解上用上述三层最稳:独立 open 通常产生不同的打开文件对象与偏移,fork/dup 则可共享同一打开文件对象和偏移。
★ 考过 2014、2017、2020
b_279_6open 和 close 各做了什么? ★1考¶
open 的完整过程:
- 逐级遍历目录,把目录文件从磁盘加载到内存,定位目标文件的目录项
- 提取索引节点编号,查找/装入对应的 inode/vnode 元数据
- 为本次独立 open 建立打开文件对象,初始化当前偏移、打开模式与引用计数;若通过 fork/dup 复制描述符,则可直接增加既有打开文件对象的引用计数
- 在进程打开文件表中分配新表项,指向相应打开文件对象
- 把该表项的索引号(文件描述符)返回给用户
close 的过程:从进程打开文件表删除对应项 → 打开文件对象的引用计数减 1 → ⚠️ 减至 0 才释放该打开文件对象;inode/vnode 是否可回收还要看其他打开引用、硬链接与缓存状态。
★ 考过 2023
b_279_8文件名是打开文件表的组成部分吗? ★3考¶
⚠️ 不是。 因为一旦通过文件名定位到磁盘上的 FCB,后续操作便不再需要文件名。
用于访问打开文件表的索引号称为文件描述符(Linux)或文件句柄(Windows)。
⚠️ 核心考点:一旦成功执行 open(),后续所有文件操作(read()、write()、lseek()、close())均不再使用文件名,而是通过文件描述符进行。
★ 考过 2012、2017、2024
b_279_104.2.8 文件共享¶
硬链接是怎么实现共享的? ★2考¶
基于索引节点:⚠️ 文件的物理地址和属性不再存放于目录项,而是集中存储在索引节点内;目录项仅含文件名 + 指向索引节点的指针。
索引节点里有链接计数 count(引用计数),记录当前指向它的目录项数量: - A 创建文件 → count = 1 - B 共享 → B 的目录新增目录项指向同一索引节点,count = 2,⚠️ 但拥有者仍是 A - ⚠️ A 不能直接删除文件(否则 B 的指针悬空)—— 只能删除自己的目录项并把 count 减 1 - ⚠️ 只有 count = 0 时系统才真正释放文件及其索引节点
★ 考过 2009、2017
💡 画图法:把“目录项 → inode → 数据块”画成三层;硬链接是多个目录项箭头汇聚到同一 inode,删除一个目录项只减链接计数。
b_280_6软链接(符号链)和硬链接差在哪? ★2考¶
软链接:系统创建一个 LINK 类型的新文件 L,⚠️ 文件 L 仅包含被链接文件 F 的路径名(类似 Windows 的快捷方式)。访问时系统识别出 LINK 类型,按其中的路径名逐级查找。
关键区别: - ⚠️ 只有文件拥有者持有指向索引节点的指针,其他用户只保存路径名 - ⚠️ 拥有者删除文件 F 后不会导致其他用户指针悬空 —— 其他用户访问时只会返回访问失败,此时可安全删除该符号链接
软链接的两个代价:⚠️ 每次访问都要按路径名逐级遍历目录,可能涉及多次磁盘读取;⚠️ 符号链接本身也是一个独立文件,其索引节点也占磁盘空间。
💡 教材总结:"文件共享,'软硬'兼施" —— 硬链接是多个目录项指向同一索引节点;软链接是保存路径按需查找;⚠️ 硬链接的查找速度通常优于软链接。 💡 软链接还可用于网络文件共享:只需记录文件所在机器的网络地址 + 路径名。
★ 考过 2009、2021
b_281_3文件保护的六种访问类型?¶
读、写、执行、添加(追加不覆盖)、删除、列表清单。
⚠️ 一个重要观察:重命名、复制、编辑等高层操作通常由应用程序调用系统调用实现,真正的保护机制仅在底层提供 —— 例如复制本质上是一系列"读"操作,因此用户只要有读权限,就隐含具备了复制和打印的能力。
b_282_2;PDF 第 282 页 · b_282_6精简 ACL 把用户分成哪三类? ★1考¶
访问控制列表 ACL:为每个文件和目录附加一张列表,指定各用户名及其被允许的访问类型。 ⚠️ 优点是支持灵活复杂的策略;缺点是列表长度不可预知,空间管理开销大 → 于是有了精简 ACL。
精简 ACL 三类用户: - 拥有者:创建文件的用户 - 组:需要共享该文件且访问需求相似的一组用户 - 其他:除前两者外的所有用户
⚠️ 每种访问类型用一个二进制位表示,仅需一个 3×4 位的矩阵(读/写/删除/执行)。 ⚠️ 匹配顺序有优先级:先看是否拥有者 → 再看是否同组 → 否则按"其他"。
★ 考过 2017
b_282_7口令和加密为什么不能替代访问控制?¶
- 口令:创建时设口令存入 FCB;⚠️ 时空开销小,但通常以明文或弱保护形式存储于系统内部,安全性较低
- 加密:对文件内容加密,访问时用密钥解密;⚠️ 保密性强、不额外占用元数据空间,但有计算开销
⚠️ 根本原因:口令与加密主要防止文件被非法获取或窃取,并不区分具体的访问操作类型(读/写、执行) → 只能作为补充手段,无法替代基于权限的访问控制。
b_282_0;PDF 第 282 页 · b_282_15逻辑结构和物理结构之间有制约关系吗?¶
⚠️ 二者并无直接制约关系,但物理结构选择不当会难以体现逻辑结构的特点。
经典反例:一个逻辑上为顺序结构的文件,若采用隐式链接的物理结构,即使理论上能快速定位某条记录,实际仍需在磁盘上逐块查找。
b_283_74.3 文件系统¶
磁盘上的文件系统布局有哪几块?¶
- 主引导记录 MBR:⚠️ 位于磁盘的 0 号扇区;传统 MBR 扇区内部包含引导代码、分区表和签名,分区表记录各分区起止地址并标记活动分区
- 引导块(boot block):⚠️ 每个分区都以引导块开头,即使未安装可启动的操作系统也保留此区域;Windows 中称分区引导扇区
- 超级块(super block):⚠️ 存储文件系统的所有关键信息,系统启动或首次挂载时读入内存;内容含分区总块数、块大小、空闲块数量及指针、空闲 inode 数量及指针
- 空闲块信息:通常用位示图或空闲链表实现
- 一组 i 节点 → 根目录 → 其他文件和目录的实际数据
💡 传统 BIOS/MBR 启动链:BIOS 把 MBR 读入内存执行 → MBR 内的引导代码读取同一扇区中的分区表并找到活动分区 → 读该分区的引导块 → 引导块加载并启动操作系统。
⚠️ 校订/边界:分区表不是“位于 MBR 之后”的独立区域;UEFI/GPT 等现代启动路径也不使用这条传统链。
b_306_6文件系统在内存中有哪四种结构?¶
- 内存中的挂载表:记录每个已挂载分区的设备标识、挂载点、文件系统类型、挂载选项
- 目录项的缓存:缓存最近访问过的目录内容,加快路径解析
- 系统级的打开文件对象/表:维护打开状态、当前偏移、引用计数,并关联 inode/vnode
- 进程级的打开文件表:维护文件描述符 + 指向打开文件对象的引用
⚠️ 生命周期:挂载时加载,运行期间动态更新,卸载时释放。
b_307_0空闲表法怎么分配和回收? ★2考¶
属于连续分配方式,思想源于内存的动态分区分配。为所有空闲区维护一张空闲表(含序号、第一个空闲盘块号、空闲盘块数),按起始盘块号递增排列。
- 分配:用首次适应、最佳适应等算法,顺序扫描找第一个满足需求的空闲区
- 回收:⚠️ 判断回收区是否与前区或后区物理连续,相邻则合并
优点:⚠️ 分配效率高、显著降低磁盘 I/O 次数 —— 尤其对小型文件(1~5 个盘块),能充分发挥磁盘顺序读写的优势。
★ 考过 2019、2024
b_307_5空闲盘块链和空闲盘区链的优缺点正好相反?¶
- 空闲盘块链:以单个盘块为单位串成链;分配从链首摘取,回收插入链尾
- 优点:⚠️ 单个盘块的分配与回收极为简单
- 缺点:⚠️ 分配多个盘块要多次访问链表;链通常很长,管理开销大
- 空闲盘区链:以空闲盘区(一组连续盘块)为单位;每个盘区记本区盘块数 + 下一盘区指针
- 优点:⚠️ 分配与回收效率较高,链长较短
- 缺点:⚠️ 过程复杂,需处理盘区的分割与合并
💡 一句话:盘块链简单但慢,盘区链高效但复杂。
b_308_0位示图的两个公式? ★4考¶
一位表示一个盘块:⚠️ "0"表示空闲,"1"表示已分配;m×n 位的位示图可描述 m×n 个盘块。
分配(找到第 i 行第 j 列的 0,行列从 1 开始,每行 n 位):
然后置 map[i,j] = 1。
回收(已知盘块号 b):
然后置 map[i,j] = 0。
⚠️ 教材的行列均从 1 开始编号;若题目指定从 0 开始,公式要相应调整(这是最常见的失分点)。
优点:查找高效,便于找到一组相邻空闲块实现连续分配;⚠️ 结构紧凑、占内存极小,可常驻内存。 缺点:⚠️ 位示图大小随磁盘容量增大而增大,更适用于小型或中等规模的系统。
★ 考过 2010、2014、2015、2023
b_308_7成组链接法的分组结构?¶
UNIX 采用,融合空闲表法和空闲链表法的思想(前两者管理结构随磁盘容量增大而过度膨胀,不适用于大型文件系统)。
结构:所有空闲盘块分组(例如每组 100 块);⚠️ 除最后一组外,每组的第一个盘块用作索引块,记录下一组所有空闲盘块的块号及数量,索引块依次链接成链。 ⚠️ 挂载时把第一组的信息加载到内存的专用栈 —— 空闲盘块号栈。
教材例(空闲区 201~7999):第一组 201~300 …… 次末组 7801~7900,最末组 7901~7999(共 99 块);⚠️ 最末组的块号由前一组的最后一个盘块(7900 号)记录,其中第一个盘块号为"0",作为整条空闲链的结束标志。
💡 精髓:"分组 + 索引 + 链接" —— 既避免长链表遍历,又无须维护完整空闲表。
💡 做题先画三层:超级块中的当前组(含空闲数 N)→ 当前组的块号栈 → 作为索引块的组首/组尾块所保存的下一组 N 与块号。不同题图对“第一个/最后一个”的叙述可能不同,以题图的 N、0 结束标志和超级块当前内容为准。
b_309_1;PDF 第 309 页 · b_309_2成组链接法分配和回收的临界情况?¶
分配:从栈顶取一个盘块号分配,栈指针上移,空闲数减 1。 ⚠️ 若栈指针到达栈底(当前组分配完)→ 先把该栈底盘块的内容(下一组的块号列表)读入栈更新,再把原栈底所指的盘块本身分配出去。 教材例:依次分配 201~299;要分配 300 号时,先把它的内容读入栈,再把 300 号本身分配出去。
回收:释放的盘块号压入栈顶,栈指针下移,空闲数加 1。 ⚠️ 若栈已满(如达到 100 项) → 把当前栈中全部盘块号写入这个新回收的盘块,使其成为新的索引块;把该盘块号设为新的栈底,空闲数重置为 1。
⚠️ 空闲盘块号栈等关键信息存储在磁盘固定位置 —— UNIX 中这一区域称为超级块,运行中要持续维护内存副本与磁盘副本的一致性。
💡 画前后状态,不背口号:分配时先让 N 减 1,再判断是否需要把索引块内容装入超级块;回收时先看当前组是否已满,满则把旧组写入新回收块,再让该块成为新组索引。
b_309_74.3.3 虚拟文件系统¶
VFS 解决了什么问题? ★1考¶
现代系统要支持 ext4、NTFS、FAT 等多种文件系统,它们在磁盘组织方式、元数据格式和操作方法上各不相同。
VFS 位于用户程序与具体文件系统之间,向上提供统一的文件操作接口 —— 程序只需调用标准系统调用(open()、write()),VFS 负责把请求转发给相应的文件系统。
⚠️ VFS 本身并不是一种真正的文件系统 —— 它仅存在于内存中,不占用磁盘空间,随系统启动而建立,随系统关闭而释放。
★ 考过 2025
b_310_1VFS 的四种对象?¶
采用面向对象设计,每个对象都包含数据成员和一组操作函数指针,这些函数由具体的文件系统提供: - 超级块对象:表示一个已挂载的文件系统,记录块大小、总块数、空闲块数量、文件系统类型 - V 节点(vnode)对象:⚠️ 最重要的抽象对象,在内存中表示一个具体的文件或目录;向上提供统一的文件属性,向下用指针指向该文件系统私有的元数据结构;⚠️ 仅在文件首次被访问时动态创建,引用计数归零后自动释放 - 目录项对象:表示路径中的一个组成部分(如 /home/user/file 中的 user);⚠️ 不直接对应磁盘上的固定结构,而是解析路径时动态生成的内存缓存 - 文件对象:表示一个进程所打开的文件("文件在进程中的运行实例");保存文件指针、访问模式、引用计数
⚠️ V 节点 ≠ 磁盘上的 inode:vnode 是 VFS 创建的内存对象,与 inode 通过指针关联 —— V 节点提供统一接口,inode 提供实际存储信息。
b_310_8write() 调用在 VFS 里怎么走?¶
write(fd, buf, n) → 内核进入 VFS 层执行 sys_write() → 按 fd 定位到打开文件对象 → 获取关联的 V 节点 → ⚠️ 利用 V 节点中的操作函数指针调用具体文件系统写方法 → 先写入页/块缓存;达到回写条件或要求同步持久化时,才经块层/调度队列/驱动写入设备。
💡 只要新文件系统实现了 VFS 定义的接口,就能被系统识别、挂载并使用。
⚠️ 校订/边界:buffered write 返回不等于物理介质已经写完;读操作也应先查内核缓存,命中即可免去磁盘 I/O。
b_311_3;PDF 第 311 页 · b_311_5挂载点有什么限制?Windows 和 UNIX 有何不同?¶
挂载(Mounting):把某个设备上的文件系统挂到目录树中的一个目录后,即可通过该目录访问该设备上的文件(这里的设备是逻辑设备,如同一磁盘的不同分区)。
⚠️ 两条铁律:同一个设备可以被挂载到多个不同的挂载点;但同一挂载点在同一时刻只能挂载一个设备。
- Windows:用驱动器号(C:、D:)标识分区(卷),⚠️ 每个分区拥有独立的目录树;较新版本也支持挂载到任意目录(装入点);启动时自动探测并挂载
- UNIX:⚠️ 以单一的根文件系统为基础,根文件系统在启动时由内核直接挂载;其他所有文件系统都必须挂载到根文件系统中的某个目录(挂载点)下才能访问
命令:mount -t ext2 /dev/fd0 /flp,卸载用 umount。
b_311_7;PDF 第 311 页 · b_311_8【疑难点】第4章¶
三种物理分配方式访问第 n 条记录要几次磁盘访问?¶
| 访问第 n 条记录 | 优点 | 缺点 | |
|---|---|---|---|
| 连续分配 | ⚠️ 1 次 | 顺序存取快,定长时可随机访问 | 要求连续空间、产生碎片、不利于动态扩充 |
| 链接分配 | ⚠️ n 次 | 解决外存碎片、利用率高、动态增长方便 | 只能顺序访问、查找效率低、指针占空间 |
| 索引分配 | ⚠️ m 级需 m+1 次 | 可随机访问、易于增删 | 索引表占空间、查找策略影响效率 |
💡 这张表是选择题高频,"1 次 / n 次 / m+1 次"务必背准。
b_316_13文件打开过程的三步(疑难点版)?¶
- ① 检索目录 —— ⚠️ 要求打开的文件应是已创建的、登记在文件目录中的文件,否则出错;检索到后把磁盘 inode 复制到活动 inode 表中
- ② 权限比较 —— ⚠️ 把参数 mode 给出的打开方式与活动 inode 中记录的文件访问权限比较,合法才算成功
- ③ 分配表项 —— 分配用户打开文件表表项和系统打开文件表表项,设置初值并用指针建立与活动 inode 的联系,把文件描述符 fd 返回给调用者
b_316_15【易混点】第4章成对概念对照¶
| 概念 A | 概念 B | 一句话切分 |
|---|---|---|
| 逻辑结构 | 物理结构 | 用户看到的组织形式 vs 外存上的实际存放,对用户透明 |
| 无结构文件 | 有结构文件 | 流式、字节流 vs 记录式 |
| 定长记录 | 变长记录 | 可按偏移随机访问 vs 只能顺序查找 |
| 顺序文件串结构 | 顺序结构 | 按时间存、必须顺扫 vs 按键字有序、可折半 |
| 索引文件 | 索引顺序文件 | 每条记录一个索引项 vs 每组首记录一个索引项(m=√N 最优) |
| FCB | inode | 文件名与描述信息在一起 vs 分离,目录项只留"文件名+inode 号" |
| 磁盘索引节点 | 内存索引节点 | 永久档案 vs 多了 inode 号/状态/访问计数/设备号/链接指针 |
| 单级/两级 | 树形/无环图 | 不能重名、不能分类 vs 能分类 / 能共享(要引用计数) |
| 绝对路径 | 相对路径 | 从根目录;同一 inode 可有多条硬链接绝对路径 vs 从当前工作目录 |
| 线性列表 | 哈希表 | 简单但查找慢 vs 快但要处理冲突 |
| 连续分配 | 链接分配 | 1 次访盘、有外部碎片 vs n 次访盘、无外部碎片 |
| 隐式链接 | 显式链接(FAT) | 指针在数据块里、逐块读链 vs 指针集中在可缓存的 FAT;仍沿表项链,但无须逐块读数据 |
| 单级索引 | 混合索引 | 小文件浪费索引块 vs 按文件大小分档:直接/一次/二次/三次间址 |
| 簇 | 盘块 | 若干连续盘块,减少指针但有内部碎片 vs 基本 I/O 单位 |
| 硬链接 | 软链接 | 多目录项指向同一 inode、count 归零才删、查找快 vs 存路径名、拥有者删了只是访问失败 |
| 口令/加密 | 访问控制 | 防非法获取,不区分操作类型 vs 精细管理读写执行权限 |
| 打开文件对象 | 进程 fd 表 | 当前偏移/打开状态/引用计数 vs fd、描述符标志、指向打开对象的引用 |
| 文件名 | 文件描述符 | open 前用 vs open 后所有操作都用它 |
| 空闲表法/空闲盘区链 | 空闲盘块链 | 以盘区为单位、效率高 vs 以盘块为单位、简单但链长 |
| 位示图 | 成组链接 | 一位一块、适合中小系统 vs 分组+索引+链接、适合大型系统(UNIX) |
| vnode | inode | VFS 的内存对象、统一接口 vs 具体文件系统的磁盘元数据 |
【必背数字】第4章¶
| 数字 | 含义 |
|---|---|
| m = √N | 索引顺序文件分组数最优值(平均查找 m/2 + s/2) |
| N/2 | 普通顺序文件的平均查找次数 |
| 64B / 1KB / 16 个 / 20 次 | 教材例:FCB 大小 / 盘块 / 每块 FCB 数 / 平均启动磁盘次数 |
| 16B(14B 文件名 + 2B inode 号)/ 64 个 / 1/4 | UNIX 目录项 / 每块目录项数 / 磁盘启动次数降幅 |
| 13 个地址项 | UNIX 索引节点 i.addr(0)~i.addr(12) |
| 10 个直接 + 1 次 + 2 次 + 3 次间址 | 混合索引的四档 |
| 40KB / 4MB / 4GB / 4TB | 直接 / 一次间址 / 二次间址 / 三次间址的容量(4KB 盘块) |
| 1024 | 一个索引块容纳的盘块号数(4KB ÷ 4B) |
| 1 次 / n 次 / m+1 次 | 连续 / 链接 / m 级索引访问第 n 条记录的磁盘访问次数 |
| −1 / −2 | FAT 中标记最后一块 / 空闲块 |
| b = n(i−1)+j | 位示图分配公式(行列从 1 开始) |
| i=(b−1)DIV n+1, j=(b−1)MOD n+1 | 位示图回收公式 |
| 100 个 / 0 | 成组链接每组盘块数 / 空闲链结束标志 |
| 0 号扇区 | MBR 所在位置 |
| 3×4 位矩阵 | 精简 ACL(三类用户 × 读写删执行) |