文件

  • 文件是操作系统中最为常见的对象
  • 有名称的一组相关信息的集合
  • 文件是信息的一种抽象机制,提供将信息保存在外存并方便读取的手段

文件结构

逻辑结构(用户视角)

  • 流式文件(字节流):文件由字节序列组成,无内部结构,如 .txt, .bin
    • UNIX/Linux 默认采用流式文件,所有文件均视为无结构的字节流
  • 记录式文件:文件由若干逻辑记录组成,每条记录有特定结构
    • 如数据库文件,每条记录包含多个字段(学号、姓名、成绩等)
    • 早期 OS(如 IBM OS/360)广泛使用,现代 OS 已较少直接在文件系统层支持

物理结构(存储设备上的组织方式)

  • 连续结构:文件占用磁盘上连续的物理块
    • 优点:顺序访问性能好(磁头移动少),直接访问易实现(通过偏移量计算块号)
    • 缺点:需预知文件大小,易产生外部碎片,不利于文件增长
  • 链接结构:文件的数据块通过指针链链接在一起
    • 隐式链接:每个数据块含指向下一块的指针,只支持顺序访问
    • 显式链接(FAT):将所有链接指针集中存放在文件分配表(FAT)中,支持直接访问
    • 优点:无外部碎片,易于动态增长
    • 缺点:顺序访问慢(随机IO),指针占用存储空间
  • 索引结构:为每个文件建立索引块,存放所有数据块的指针
    • 优点:直接访问快,无外部碎片
    • 缺点:索引块本身占用额外空间
    • UNIX 采用混合索引(多级索引),兼顾小文件和大文件

访问方式

  • 顺序访问:按字节/记录从前向后顺序读写
    • 文件指针自动后移,如磁带式访问
    • 适用于大多数文本文件、日志文件
  • 直接访问(随机访问):指定位置(字节偏移或记录号)直接读写
    • 如数据库、索引文件
    • 支持 lseek() 定位后读写

文件控制块(FCB)

  • 为管理文件而设置的数据结构,保存文件的全部属性信息
  • 包含以下主要字段:
    • 文件名:用户可见的文件标识
    • 文件类型:如普通文件、目录文件、特殊文件等
    • 文件号(inode 号):文件系统内部的唯一标识
    • 文件长度:当前文件大小(字节数)
    • 存储位置:文件数据在磁盘上的物理位置(块号指针)
    • 访问权限:所有者、同组用户、其他用户的读/写/执行权限
    • 时间戳:创建时间、最后修改时间、最后访问时间
    • 链接计数:有多少个文件名指向该文件(硬链接计数)
    • 在 UNIX 中,FCB 即为 inode(索引节点),但 inode 不包含文件名,文件名存放在目录文件中

文件目录结构

  • 目录:以文件形式存在(目录文件),内容是一系列 FCB 或目录项的集合
  • 目录的作用:实现”按名存取”,将文件名映射为文件的物理位置

单级目录

  • 所有文件放在一个目录中,系统只有一张线性(或哈希)文件目录表
  • 优点:简单,易于实现
  • 缺点:名称冲突(不同用户不能使用相同文件名),不支持文件分组,线性搜索效率低

二级目录

  • 分为主文件目录(MFD)用户文件目录(UFD)
  • MFD 记录各个用户的用户名和其 UFD 的位置
  • 每个用户拥有自己的 UFD,只包含该用户的文件
  • 优点:不同用户可使用相同文件名,支持多用户隔离
  • 缺点:用户内部仍无法对文件分类组织,“路径”概念开始出现(如 /userA/file1

树形目录

  • 多级层次结构,支持文件分组
  • 引入当前目录(工作目录):用户当前所在的目录,简化路径表示
  • 绝对路径:从根目录(/)开始的完整路径
    • /home/user/docs/report.txt
  • 相对路径:从当前目录开始的路径
    • ./docs/report.txtdocs/report.txt
  • 优点:层次清晰,支持文件分组,不同目录下可包含同名文件
  • 缺点:共享文件需通过路径链接

无环图目录

  • 在树形目录基础上增加共享链接,允许多个路径指向同一文件
  • 支持文件共享(通过硬链接或符号链接实现)
  • 需将 FCB 与文件内容分离:FCB 中存放文件物理位置,目录项中存放文件名和 FCB 指针
  • 多个目录项可指向同一个 FCB,实现共享
  • 注意:即使从某个目录中删除该文件,只要还有其他链接,文件内容就不应删除(引用计数机制)

文件存储空间管理

  • 操作系统需要跟踪磁盘上空闲块,分配新块给文件,回收删除文件释放的块

空闲表法

  • 系统维护一张空闲表,记录每个连续空闲区的起始块号和块数
  • 适用于连续结构文件分配

空闲链表法

  • 将所有空闲块链接成一个链表,分配时从链头取块,回收时挂回链尾
  • 空闲盘块链:以数据块为单位链接
  • 空闲盘区链:以连续空闲区为单位链接

位图法(Bit Map)

  • 用一个二进制位(bit)对应一个物理块,0 表示空闲,1 表示已占用
  • 优点:查找空闲块效率高(利用 CPU 位操作指令),占用空间小
  • 缺点:位图需全部调入内存才能工作(大容量磁盘下位图较大)
  • 现代文件系统(如 ext 系列)广泛采用位图管理

成组链接法(UNIX 系统)

  • 将空闲块分组管理,每 50 个空闲块为一组
  • 超级块(Super Block):记录下一组空闲块的块号和块数
  • 分配时从第一组中取块,组内块用完时读入下一组的超级块信息
  • 回收时将释放的块加入第一组,第一组满时再写入超级块
  • 优点:兼顾了空间利用率和分配效率,避免维护一个巨大的链表或位图
  • 缺点:频繁的超级块更新操作可能影响性能