初识文件管理
- 文件的定义:一组有意义的信息的集合
- 文件的属性:文件名、标识符、类型、位置、大小、保护信息……
- 文件内部应该如何被组织起来(文件的逻辑结构)
- 文件之间应该如何被组织起来(目录结构)
- 操作系统向上提供的几个最基本的功能
- 创建文件(create系统调用)
- 删除文件(delete系统调用)
- 读文件(read系统调用)
- 写文件(write系统调用)
- 打开文件(open系统调用)
- 关闭文件(close系统调用)
- 文件应如何存放在外存中(文件的物理结构)
- 操作系统如何管理外存中的空闲块(存储空间的管理)
- 操作系统需要提供的其他文件管理功能
- 文件共享
- 文件保护
文件的逻辑结构
无结构文件:由二进制流或字符组成,无明显的逻辑结构
有结构文件
- 由记录组成,分为定长记录、可变长记录
- 逻辑结构
- 顺序文件
- 索引文件
- 索引顺序文件
- 顺序文件
- 串结构:记录顺序与关键字无关
- 顺序结构:记录按关键字顺序排列
- 可变长记录的顺序文件无法实现随机存储,定长记录可以
- 最大缺点:不方便 增加/删除 记录
![顺序文件]()
- 索引文件
- 建立一张索引表,每个记录对应一个表项。各记录不用保持顺序,方便增加/删除记录
- ==索引表本身就是定长记录的顺序文件==,一个索引表项就是一条定长记录,因此索引文件可支持随机存储
- ==若索引表按关键字顺序排列,则可支持快速搜索==
- 解决了顺序文件不方便增/删记录的问题,同时让不定长记录的文件实现了随机存储。但索引表可能占用很多空间
![索引文件]()
- 索引顺序文件
- 将记录分组,每组对应一个索引表项
- 检索记录时先顺序查索引表,找到分组,再顺序查找分组
- 当记录过多时,可建立多级索引表
![索引顺序文件]()
文件目录
- 文件目录的实现
- 一个文件对应一个FCB,一个FCB就是一个目录项,多个FCB组成文件目录
- 对目录的操作:搜索、创建文件、删除文件、显示文件、修改文件
- 目录结构
- 单级目录结构:一个系统只有一张目录表,==不允许文件重名==
- 两级目录结构:不同用户的文件可以重名,但==不能对文件进行分类==
- 多级(树形)目录结构
- 不同目录下的文件可以重名,可以对文件进行分类,==不方便文件共享==
- 系统根据“文件路径”找到目标文件
- 从根目录出发的路径是“绝对路径”
- 从“当前目录”出发的路径是“相对路径”
- 无环图目录结构
- 在树形目录结构的基础上,增加一些指向同一节点的有向边,使整个目录成为一个有向无环图
- 为共享结点设置一个共享计数器,==计数器为0时才真正删除该结点==
- 索引结点
- ==除了文件名之外的所有信息都放到索引结点中,每个文件对应一个索引结点==
- 目录项中只包含文件名、索引结点指针,因此每个目录项的长度大幅减小
- 由于目录项长度减小,因此每个磁盘块可以存放更多个目录项,因此检索文件时磁盘I/O的次数就少了很多
文件的物理结构
顺序分配
- 实现:为文件分配的必须是连续的磁盘块
- 目录项内容:起始块号、文件长度
- 优点
- 顺序存取速度快
- 支持随机访问
- 缺点
- 会产生碎片
- 不利于文件扩展
链接分配——隐式链接
- 实现:除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针
- 目录项内容:起始块号、结束快号
- 优点
- 可解决碎片问题,外存利用率高
- 文件拓展实现方便
- 缺点
- 只能顺序存储,不能随机访问
链接分配——显式链接
- 实现:建立一张文件分配表(FAT),显式记录盘块的先后关系(开机后FAT常驻内存)
- 目录项内容:起始块号
- 优点
- 除了拥有隐式链接的优点之外,还可通过查询内存中的FAT实现随机访问
- 缺点
- FAT需要占用一定的存储空间
索引分配
- 实现:为文件数据块建立索引表。若文件太大,可采用链接方案、多层索引、混合索引
- 目录项内容:
- 链接方案记录的是第一个索引块的块号
- 多层/混合索引记录的是顶级索引块的块号
- 优点
- 支持随机访问
- 易于实现文件的扩展
- 缺点
- 索引表需占用一定的存储空间
- 访问数据块前需要先读入索引块
- 若采用链接方案,查找索引时可能需要很多次读磁盘操作
- 链接方案:如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放
![链接方案]()
- 多层索引:原理类似于多级页表
![多层索引]()
- 混合索引:多种索引分配方式的结合
![混合索引]()
逻辑结构 VS 物理结构
- 逻辑结构
- 用户(文件创建者)的视角看到的样子
- 在用户看来,整个文件占用连续的逻辑地址空间
- 文件内部的信息组织完全由用户自己决定,操作系统并不关心
- 物理结构
- 由操作系统决定文件采用什么物理结构存储
- 操作系统负责将逻辑地址转变为(逻辑块号, 块内偏移量)的形式,并负责实现逻辑块号到物理块号的映射
文件存储空间管理
存储空间的划分与初始化
- 文件卷(逻辑卷),目录区、文件区的概念
- ==目录区包含文件目录、空闲表、位示图、超级块等用于文件管理的数据==
空闲表法
- 空闲表中记录每个连续空闲区的起始盘块号、盘块数
- 分配时可采用==首次适应、最佳适应等策略;回收时注意表项的合并问题==
空闲链表法
空闲盘块链
- 以==盘块==为单位组成一条空闲链
- 分配时从链头依次取出空闲块,回收时将空闲块插到链尾
空闲盘区链
- 以==盘区==为单位组成一条空闲链
- 分配时可采用首次适应、最佳适应等策略;回收时注意相邻空闲盘区合并的问题
位示图法
- 一个二进制位对应一个盘块。(字号, 位号) 或 (行号, 列号) 与盘块号一一对应
成组链接法
- UNIX采用的策略,适合大型文件系统
文件的基本操作
- 创建文件:分配外存空间,创建目录项
- 删除文件:回收外存空间,删除目录项
- 打开文件
- ==将目录项中的信息复制到内存中的打开文件表中,并将打开文件表的索引号返回给用户==
- 打开文件之后,对文件的操作不再需要每次都查询目录,可以根据内存中的打开文件表进行操作
- 每个进程有自己的打开文件表,系统中也有一张总的打开文件表
- 进程打开文件表中特有的属性:读写指针、访问权限(只读?读写?)
- 系统打开文件表中特有的属性:打开计数器(有多少个进程打开了该文件)
- 关闭文件
- 将进程打开文件表中的相应表项删除
- 系统打开文件表的打开计数器减1,若打开计数器为0,则删除系统表的表项
- 读文件:根据读指针、读入数据量、内存位置==将文件数据从外存读入内存==
- 写文件:根据写指针、写出数据量、内存位置将文件数据从内存写出外存
文件共享
- 硬链接
- 各个用户的目录项指向同一个索引结点
- 索引结点中需要有链接计数count
- 某用户想删除文件时,只是删除该用户的目录项,且count–
- 只有count == 0时才能真正删除文件数据和索引结点,否则会导致指针悬空
- 软链接(符号链接)
- 在一个Link型的文件中记录共享文件的存放地址(Windows快捷方式)
- 操作系统根据路径一层层查找目录,最终找到共享文件
- 即使软链接指向的共享文件已被删除,Link型文件依然存在,只是通过Link型文件中的路径去查找共享文件会失败(找不到对应目录项)
- 由于用软链接的方式访问共享文件时要查询多级目录,会有多次磁盘I/O,因此用软链接访问共享文件的速度要比硬链接更慢
文件保护
- 口令保护
- 为文件设置一个“口令”,用户想要访问文件时需要提供口令,由系统验证口令是否正确
- 实现开销小,但“口令”一般存放在FCB或索引结点中(也就是存放在系统中),因此不太安全
- 加密保护
- 用一个“密码”对文件加密,用户想要访问文件时,需要提供相同的“密码”才能正确的解密
- 安全性高,但加密/解密需要耗费一定的时间(Eg:异或加密)
- 访问控制
- 用一个访问控制表(ACL)记录各个用户(或各组用户)对文件的访问权限
- 对文件的访问类型可以分为:读/写/执行/删除 等
- 实现灵活,可以实现复杂的文件保护功能
文件系统的层次结构

假设某用户请求删除“D:/dev/学生信息.xlsx”的最后100条记录
- 用户需要通过操作系统提供的接口发出上述请求——==用户接口==
- 由于用户提供的是文件的存放路径,因此需要操作系统一层一层地查找目录,找到对应的目录项——==文件目录系统==
- 不同的用户对文件有不同的操作权限,因此为了保证安全,需要检查用户是否有访问权限——==存取控制模块(存取控制验证层)==
- 验证了用户的访问权限之后,需要把用户提供的“记录号”转变为对应的逻辑地址——==逻辑文件系统与文件信息缓冲区==
- 知道了目标记录对应的逻辑地址后,还需要转换成实际的物理地址——==物理文件系统==
- 要删除这条记录必定要对磁盘设备发出请求–设备管理程序模块将这些空闲盘块回收——==辅助分配模块==
- 删除这些记录后,会有一些盘块空闲,因此要将这些空闲盘块回收——==辅助分配模块==
文件系统布局







虚拟文件系统
- 虚拟文件系统的特点
- 向上层用户进程提供统一标准的系统调用接口,屏蔽底层具体文件系统的实现差异
- VFS要求下层的文件系统必须实现某些规定的函数功能
- 存在的问题:不同的文件系统,表示文件数据结构各不相同。打开文件后,其在内存中的表示就不同
- 文件系统挂载:即文件系统安装/装载
- 在VFS中注册新挂载的文件系统。内存中的挂载表包含每个文件系统的相关信息,包括文件系统类型、容量大小等
- 新挂载的文件系统,要向VFS提供一个函数地址列表
- 将新文件系统加到挂载点,也就是将新文件系统挂载在某个父目录下





