第六章:文件管理

6.1 文件的基本概念

文件是计算机中信息存储的基本单位——用户和OS通过文件来组织和管理数据。

文件的属性:

  • 文件名:人类可识别的标识。
  • 类型:如.exe, .txt, .jpg。
  • 位置:指向文件在设备上的位置的指针。
  • 大小:字节数。
  • 保护:访问控制信息(读/写/执行权限)。
  • 时间戳:创建、修改、访问时间。

文件操作:创建、打开、读、写、关闭、删除。

6.2 文件的逻辑结构

从用户角度看到的文件组织形式。

结构 描述 优点 缺点
顺序文件 记录按顺序排列 访问快(尤其定长记录) 增/删困难
索引文件 建立索引表(关键字→指针) 支持随机访问 额外索引开销
索引顺序文件 先分组,每组建索引 结合两者优点 较复杂

6.3 文件的物理结构

从OS角度看在磁盘上如何组织文件数据。

结构 描述 优点 缺点
连续分配 文件数据存在连续的磁盘块上 访问快(顺序和随机都高效) 有外部碎片,扩展困难
链接分配 每个数据块存有指向下一块的指针 无外部碎片,扩展方便 随机访问慢,指针占用空间
索引分配 文件有一个索引块,记录所有数据块的位置 支持随机访问,扩展方便 索引块占用空间

链接分配的两种方式:

  • 隐式链接:每个数据块存有指向下一块的指针。只能顺序访问。
  • 显式链接(FAT——文件分配表):将所有磁盘块的链接指针单独放在内存的FAT表中。在FAT中查找下一块非常快(内存访问)。

📌 408考点提示:FAT是常考内容——FAT本质是一张表,每个表项存放对应磁盘块的下一块指针。FAT存储在内存中,所以通过FAT查找速度很快。

索引分配中的三个层次:

  1. 单级索引:一个索引块记录所有数据块号——文件大时需要多个索引块。
  2. 多级索引:如二级索引,索引块指向多个索引块——支持超大文件。
  3. 混合索引(Unix的inode):结合直接块(快速访问小文件)+ 单级/多级索引块(支持大文件)。

💡 记忆技巧:连续≈链表(顺序访问快但难扩展),链接≈链表+指针,索引≈图书目录(查目录找内容)。

6.4 目录结构

目录(文件夹) 是文件的索引,每个目录项包含文件名和指向文件的指针。

6.4.1 单级目录

所有文件在一个目录中。问题:命名冲突(不能重名),不适合多用户。

6.4.2 两级目录

每个用户有自己的文件目录(UFD),系统有主文件目录(MFD)。解决了命名冲突,但不支持子目录。

6.4.3 树形目录(最常用)

从根目录→子目录→文件,形成树形结构。用户用绝对路径(从根开始)或相对路径(从当前目录开始)访问文件。典型:Unix/Linux/Windows。

目录操作:创建/删除目录、列出目录、改变当前目录等。

当前目录:每个进程有一个当前目录,相对路径基于当前目录解析。

6.4.4 无环图目录

在树形目录的基础上增加共享(用链接等方式),使多个目录可以指向同一文件。注意避免循环(环)——引入共享后可能导致循环目录,要防止。

6.5 文件共享

方式 原理 特点
硬链接(基于索引结点的共享) 多个目录指向同一个索引结点(inode)。每个文件有link count,删除到0才真正删除文件 不能跨文件系统,不能链接目录
软链接/符号链接(基于路径名的共享) 创建一个新文件(.lnk/符号链接),内容指向目标文件的路径 可跨文件系统,原文件删除后链接失效

📌 408考点提示:硬链接和软链接的区别是常见选择题。硬链接共享inode(同一文件多个名),软链接是独立的文件(指向另一个文件)。

6.6 文件保护

访问控制:为每个文件设置访问控制列表(ACL)或权限位。

Unix权限模型(简洁):

  • 三类用户:owner(文件主)、group(同组用户)、others(其他人)。
  • 三种权限:r(读)、w(写)、x(执行),用二进制表示:rwx = 111 = 7。

6.7 文件系统实现

6.7.1 文件系统的布局

典型磁盘分区(卷)的文件系统布局:

区域 内容
引导块 引导信息(MBR/GPT)
超级块 文件系统的全局信息(大小、块数、空闲块数等)
空闲块管理 空闲块位图/空闲链表
i节点区(inode) 存放所有文件的索引结点
数据区 文件数据块

6.7.2 目录实现

线性列表:简单但查找慢(O(n))。 哈希表:查找快(O(1)),但需要处理冲突,可能不适合大目录。

6.7.3 FAT文件系统

FAT表中的每一项对应一个磁盘块,值表示下一块的块号(或用特殊值标记文件结束/坏块/空闲)。

FAT计算:假设磁盘块大小为4KB,磁盘容量为32GB,则FAT需要多少项?

  • 块数 = 32GB/4KB = 8M(8×10^6)项
  • 若每项用4字节(32位,可表示2^32个块),则FAT大小 = 8M × 4B = 32MB

6.7.4 Unix/Linux i节点(inode)

inode是文件的索引结点,包含文件的属性信息和指向数据块的指针。文件名和inode是分开存放的(文件名在目录中,inode在inode区)。

典型的inode结构(混合索引):

  • 12个直接块指针
  • 1个一级间接块指针
  • 1个二级间接块指针
  • 1个三级间接块指针

假设块大小=4KB,指针占4B,则:

  • 一个间接块可存 = 4KB/4B = 1024个指针
  • 直接块可存 = 12 × 4KB = 48KB
  • 一级间接可存 = 1024 × 4KB = 4MB
  • 二级间接可存 = 1024 × 1024 × 4KB = 4GB
  • 三级间接可存 = 1024 × 1024 × 1024 × 4KB = 4TB

6.8 磁盘结构

磁盘的物理结构:

  • 磁道:盘面上的同心圆。
  • 扇区:磁道上的一段弧,是磁盘读写的基本单位(通常512B)。
  • 柱面:所有盘面上同一半径的磁道集合。
  • 磁头:每个盘面有一个读写磁头。

磁盘访问时间 = 寻道时间 + 旋转延迟 + 传输时间

  • 寻道时间:磁头移动到目标磁道的时间(最慢的部分,占总时间的70%以上)。
  • 旋转延迟:目标扇区旋转到磁头下的时间(平均半圈旋转时间)。
  • 传输时间:读写数据的时间。

6.9 磁盘调度算法

磁盘调度的核心目标是减少寻道时间。

算法 策略 特点
FCFS(先来先服务) 按请求顺序 简单但寻道时间长
SSTF(最短寻道时间优先) 选离当前磁头最近的请求 平均寻道时间较短,但可能产生"饥饿"(远处的请求很难被服务)
SCAN(电梯算法) 磁头单向移动,沿途服务所有请求 解决了饥饿问题,但扫到一端才折返
C-SCAN(循环扫描) 只单向服务,到一端后快速返回 更均匀的等待时间
LOOK SCAN的改进——到最远请求处就折返,不用扫到底 比SCAN效率更高
C-LOOK C-SCAN的改进——到最远请求处就返回起点 比C-SCAN效率更高

💡 记忆技巧:SCAN/电梯算法就像电梯——一直往上直到没人按了再往下。LOOK是SCAN的优化版——电梯送到最高层有人的楼层就掉头,不用到楼顶。

📌 408考点提示:磁盘调度算法的寻道计算是408常考的计算题。关键:明确磁头当前位置和方向,计算寻道长度。

6.10 磁盘的管理

格式化:分为低级格式化(物理格式化——划分扇区)和高级格式化(逻辑格式化——写入文件系统结构)。

分区:将一个物理磁盘划分为多个逻辑分区(每个分区有自己的文件系统)。

引导块:磁盘的第一个扇区(MBR)包含引导代码和分区表。

坏块管理:磁盘出厂时就有坏道/坏块,控制器通过备用扇区替换坏块(也称为"扇区备份")。

6.10.1 磁盘缓存与RAID

磁盘缓存:在内存中划分一块区域作为磁盘块的缓存,减少磁盘访问次数。

RAID(冗余磁盘阵列):

  • RAID 0:条带化——数据分块到多个磁盘,读写快但无冗余。
  • RAID 1:镜像——数据完全复制到两个磁盘,有冗余但存储利用率低。
  • RAID 5:条带+奇偶校验——一个磁盘损坏可恢复,空间利用率较高。
  • RAID 10:条带+镜像——性能和冗余兼备。

6.10.2 文件系统的性能优化

块缓存(Buffer Cache/Page Cache):在内存中缓存最近访问的文件块。Linux使用Page Cache统一管理文件和磁盘缓存。

提前读取(Read-ahead):OS预测进程的访问模式,提前将后续磁盘块读入缓存,减少等待时间。

延迟写入(Delayed Write):写操作先写入缓存,稍后批量写入磁盘——提高性能,但增加了断电丢数据的风险。

示例题

示例1(磁盘调度):磁头在50号磁道,磁头正向磁道号增加方向移动。请求队列:98, 183, 37, 122, 14, 124, 65, 67。求SCAN和C-SCAN的寻道长度。

SCAN(电梯算法): 方向:从50向大号移动。 服务顺序:65, 67, 98, 122, 124, 183 → 到199(最末尾)→ 折返 → 37, 14 寻道长度 = (65-50)+(67-65)+(98-67)+(122-98)+(124-122)+(183-124)+(199-183)+(199-37)+(37-14) = 15+2+31+24+2+59+16+162+23 = 334

C-SCAN: 方向:从50向大号移动。 服务顺序:65, 67, 98, 122, 124, 183 → 到199后直接跳到0 → 14, 37 寻道长度 = (65-50)+(67-65)+(98-67)+(122-98)+(124-122)+(183-124)+(199-183)+(199-0)+(14-0)+(37-14) = 15+2+31+24+2+59+16+199+14+23 = 385

示例2(FAT计算):磁盘块大小1KB,磁盘容量40GB,FAT32中每项占4字节,问FAT表需要占多少空间?

解: 块数 = 40GB / 1KB = 40 × 2^20 = 40M 块 FAT表大小 = 40M × 4B = 160MB

如果用FAT16(每项2字节):

  • 每项2B → 只能表示65536个块
  • 最大可管理容量 = 65536 × 1KB = 64MB
  • 所以FAT16无法管理40GB的磁盘——这就是FAT32出现的必要性。

示例3(inode混合索引):Unix文件系统中,块大小4KB,指针4B,有12个直接块、1个一级间接、1个二级间接。求: (1) 单个文件的最大大小 (2) 访问文件中的第5000个字节需要几次磁盘访问(假设inode在内存中)

解: (1) 每个间接块可存指针数 = 4KB/4B = 1024个 最大大小 = 12×4KB + 1024×4KB + 1024²×4KB = 48KB + 4MB + 4GB ≈ 4.048GB

(2) 第5000个字节:

  • 前12个直接块覆盖:12×4096=49152字节
  • 5000 < 49152,所以落在直接块中
  • 块号 = 5000/4096 = 1(第2个直接块,偏移5000-4096=904)
  • 需要1次磁盘访问(读数据块——inode已在内存)

示例4(目录结构相关):在树形目录中,使用绝对路径和相对路径查找文件是什么区别?假设当前目录是/usr/bin,要访问文件/usr/bin/gcc和/usr/share/doc/readme,请分别用绝对路径和相对路径表示。

解: 绝对路径从根目录开始:/usr/bin/gcc, /usr/share/doc/readme。 相对路径从当前目录开始:

  • /usr/bin/gcc → 在当前目录下直接访问 gcc(相对路径 = gcc)
  • /usr/share/doc/readme → 先用 .. 回到 /usr,然后进入 share/doc/readme(相对路径 = ../share/doc/readme)

相对路径更短但依赖于当前目录。系统根据当前目录的inode位置解析相对路径——先找到当前目录的inode,再逐级查找子目录项。

示例5(文件物理结构分析):一个文件大小为8000字节,磁盘块大小为1024字节。请分析该文件在使用连续分配、链接分配、索引分配时分别占用的磁盘块数和需要几次磁盘访问才能访问到第7000个字节。

解: 文件需要 8000/1024 = 7.8125 ≈ 8个磁盘块。

(1) 连续分配:

  • 占用8个连续的磁盘块。
  • 第7000个字节在第7块(块号=7000/1024=6,从0计)。
  • 访问第7块只需1次磁盘访问(直接计算块号=起始块号+6)。

(2) 链接分配(隐式链接):

  • 占用8个磁盘块,每块末尾4字节存放下一块指针。
  • 实际可用数据每块=1024-4=1020字节。
  • 重新计算:需要8000/1020≈7.84,需要8块,但第8块只用了8000-7×1020=860字节。
  • 要访问第7000个字节,需要顺序读块:块0→块1→...→块6(读7次才能到达第7块),加上读取第7块本身——共8次磁盘访问。速度极慢!

(3) 索引分配:

  • 占用8个数据块+1个索引块=9个磁盘块。
  • 索引块存8个指针(占8×4=32字节,远小于1024字节)。
  • 访问第7000个字节:先读索引块(1次),找到第7块地址,再读第7块(1次)——共2次磁盘访问。

对比总结:连续分配访问最快(1次),但扩展困难;链接分配扩展方便但顺序访问极慢;索引分配介于两者之间(2次),支持随机访问且扩展方便。

本章小结

文件管理涉及文件的组织方式、目录结构、磁盘空间管理和磁盘调度。重点掌握:三种物理结构(连续/链接/索引)的对比和适用场景、FAT表的计算、inode混合索引的分析(408计算题常考)、磁盘调度算法的寻道计算、硬链接和软链接的区别。注意FAT和inode是两种不同的文件系统实现方式——FAT是"显式链接"的代表,inode是"索引分配"的代表。