# 初始文件管理
# 文件的属性
- 文件名:由创建文件的用户决定文件名,主要是为了方便用户找到文件,同一目录下不允许有重名文件
- 标识符:一个系统内的各文件标识符唯一,对用户来说毫无可读性,因此标识符只是操作系统用于区分各个文件的一种内部名称
- 类型:指明文件的类型
- 位置:文件存放的路径(让用户使用)、在外存中的地址(操作系统使用,对用户不可见)
- 大小:指明文件大小
- 创建时间、上次修改时间、文件所有者信息
- 保护信息:对文件进行保护的访问控制信息
# 文件分类
- 无结构文件:由二进制或字符流组成,又称流式文件
- 有结构文件:如数据库表,又称记录式文件
# 操作系统向上提供的功能
- 创建文件:背后调用 create 系统调用
- 读文件:背后调用 read 系统调用
- 写文件:背后调用 write 系统调用
- 删除文件:背后调用 delete 系统调用
- 打开文件:open 系统调用
- 关闭文件:close 系统调用
# 文件的逻辑结构
# 无结构文件
无结构文件:文件内部的数据就是一系列二进制流或字符流组成。又称 “流式文件”
# 有结构文件
有结构文件:由一组相似的记录组成,又称 “记录式文件”。每条记录又若干个数据项组成。如:数据库表文件。一般来说,每条记录有一个数据项可作为关键字
# 有结构文件分类
# 顺序文件
顺序文件:文件中的记录一个接一个地顺序排列(逻辑上),记录可以是定长的或可变长的。各个记录在物理上可以顺序存储或链式存储
- 串结构:记录之间的顺序与关键字无关
- 无论式定长 / 可变长记录,都无法实现随机存取,每次只能从第一个记录开始一次往后寻找
- 顺序结构:记录之间的顺序按关键字顺序排列
- 可变长记录:无法实现随机存取,每次只能从第一个记录开始往后依次进行查找
- 定长记录:
- 可实现随机存取,记录长度为 L,则第 i 个记录存放相对位置是 i * L
- 若采用串结构,无法快速找到关键字对应顺序
- 若采用顺序结构,可以快速找到关键字对应的记录(折半查找)
# 索引文件
索引表本身是定长记录的顺序文件。因此可以快速找到第 i 个记录对应的索引项,每当要增加 / 删除一个记录时,需要对索引表进行修改。由于索引文件有很快的检索速度,因此主要用于对信息处理的及时性要求比较高的场合,可以用不同的数据项建立多个索引表
# 索引顺序文件
索引顺序文件是索引文件和顺序文件思想的结合。索引顺序文件中,同样会为文件建立一张索引表,但不同的是:并不是每个记录对应一个索引表项,而是一组记录对应一个索引表项
# 文件目录
# 文件控制块
FCB 的有序集合称为 “文件目录”,一个 FCB 就是一个文件目录项。FCB 中包含了文件的基本信息(文件名、物理地址、逻辑结构、物理结构等),存取控制信息(是否可读 / 可写、禁止访问的用户名单等),使用信息(如文件的建立时间、修改时间等)。最重要,最基本的还是 文件名、文件存放的物理地址
- 搜索:当用户要使用一个文件时,系统要根据文件名搜索目录,找到该文件对应的目录项
- 创建文件:创建一个新文件时,需要在其所属的目录中增加一个目录项
- 删除文件:当删除一个文件时,需要在目录中删除相应的目录项
- 显示目录:用户可以请求显示目录的内容,如显示该目录中的所有文件及相应属性
- 修改目录:某些文件属性保存在目录中,因此这些属性变化时需要修改相应的目录项(如:文件重命名)
# 目录结构
# 单级目录结构
早期操作系统并不支持多级目录,整个系统中只建立一张目录表,每个文件占一个目录项,不允许文件重名
# 双级目录结构
早期的多用户操作系统,采用两级目录结构。分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User Flie Directory)允许不同用户的文件重名
# 多级目录结构
树形目录结构可以很方便地对文件进行分类,层次结构清晰,也能够更有效地进行文件的管理和保护
# 无环图目录结构
可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。
需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时,只是删除该用户的 FCB、并使共享计数器减 1,并不会直接删除共享结点。
只有共享计数器减为 0 时,才删除结点。
注意:共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化
# 文件保护
# 口令保护
- 为文件设置一个 “口令”(如:abc112233),用户请求访问该文件时必须提供 “口令”
- 优点:保存口令的空间开销不多,验证口令的时间开销也很小
- 缺点:正确的 “口令” 存放在系统内部,不够安全
# 加密保护
- 使用某个 “密码” 对文件进行加密,在访问文件时需要提供正确的 “密码” 才能对文件进行正确的解密
- 优点:保密性强,不需要在系统中存储 “密码”
- 缺点:编码 / 译码,或者说加密 / 解密要花费一定时间
# 访问控制
在每个文件的 FCB(或索引结点)中增加一个访问控制列表(Access-Control List, ACL),该表中记录了各个用户可以对该文件执行哪些操作
# 访问类型
# 文件共享
# 基于索引结点的共享方式(硬链接)
# 基于索引节点的共享方式(软链接)
# 文件的物理结构
# 文件分配方式 —— 连续分配
- 乱需要分配的文件顺序读 / 写速度最快
- 物理上采用连续分配的文件不方便拓展
- 物理上采用连续分配,存储空间利用率低,会产生难以利用的磁盘碎片
# 链接分配
链接分配采取离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种
# 隐式链接
- 隐式链接:除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针。文件目录包括文件第一块的指针和最后一块的指针
- 优点:很方便文件拓展,不会有碎片问题,外存利用率高
- 缺点:只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量的存储空间
# 显式链接
- 显式链接:把用于链接文件各物理块的指针显式地存放在一张表中,即 文件分配表(FAT,FileAllocation Table)。一个磁盘只会建立一张文件分配表。开机时文件分配表放入内存,并常驻内存
- 优点:很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接来说,地址转换时不需要访问磁盘,因此文件的访问效率更高
- 缺点:文件分配表的需要占用一定的存储空间
# 索引分配
- 索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块(索引表的功能类似于内存管理中的页表 —— 建立逻辑页面到物理页之间的映射关系) 。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块
- 链接方案:如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。缺点:若文件很大,索引表很长,就需要将很多个索引块链接起来。想要找到 i 号索引块,必须先依次读入 0~i-1 号索引块,这就导致磁盘 I/O 次数过多,查找效率低下
- 多层索引:建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。采用 K 层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要 K + 1 次读磁盘操作。缺点:即使是小文件,访问一个数据块依然需要 K+1 次读磁盘
- 混合索引:多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表) 。优点:对于小文件来说,访问一个数据块所需的读磁盘次数更少
- 重点:①要会根据多层索引、混合索引的结构计算出文件的最大长度(Key:各级索引表最大不能超过一个块);②要能自己分析访问某个数据块所需要的读磁盘次数(Key:FCB 中会存有指向顶级索引块的指针,因此可以根据 FCB 读入顶级索引块。每次读入下一级的索引块都需要一次读磁盘操作。另外,要注意题目条件 —— 顶级索引块是否已调入内存)
# 逻辑结构 VS 物理结构
# 文件存储空间管理
# 存储空间的划分与初始化
# 存储空间管理 —— 空闲表法
# 存储空间管理 —— 空闲链表法
# 存储空间管理 —— 位示图法
# 存储空间管理 —— 成组链接法
# 文件得基本操作
# 文件系统的层次结构
# 磁盘的结构
# 磁盘、磁道、扇区
# 盘面、柱面
# 磁盘的物理地址
# 磁盘的分类
# 磁盘的调度算法
# 一次磁盘读 / 写操作需要的时间
# 磁盘调度算法
# 先来先服务(FCFS)
按访问请求的先后顺序进行处理
# 最短寻找时间优先(SSTF)
- 每次优先响应距离磁头最近的磁道访问请求
- 贪心算法的思想:能保证眼前最优,但无法保证总的寻道时间最短
- 缺点:可能导致饥饿
# 扫描算法(SCAN)
- 只有磁头移动到最边缘的磁道才可以改变磁头移动方向
- 缺点:对各个位置磁道的响应频率不平均
# 循环扫描算法(C-SCAN)
只有磁头朝某个方向移动时才会响应请求,移动到边缘后立即让磁头返回起点,返回途中不响应任何请求
# LOCK 与 C-CLOCK
- LOCK 算法:SCAN 算法的改进,只要在磁头移动方向上不再有请求,就立即改变磁头方向
- C-LOCK 算法:C-SCAN 算法的改进,只要在磁头移动方向上不再有请求,就立即改变磁头方向
# 减少磁盘延迟时间
# 交替编号
- 具体做法:让编号相邻的扇区在物理上不相邻
- 原理:读取完一个扇区后需要一段时间处理才可以继续读入下一个扇区
# 错位命名
- 具体做法:让相邻盘面的扇区编号错位
- 原理:与交替编号的原理相同,可降低延迟时间