操作系统文件管理部分笔记

117 阅读11分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

文件管理

初识文件管理

文件的属性:

  • 文件名
  • 标识符
  • 类型
  • 位置
  • 大小
  • 创建时间
  • 上次修改时间
  • 文件所有者信息
  • 保护信息

文件数据组织形式:

  • 无结构文件(流式文件,如文本文件)
  • 有结构文件(记录式文件,如数据库表)

操作系统向上提供的功能:

  • 创建文件----create系统调用
  • 读文件----read系统调用
  • 写文件----write系统调用
  • 删除文件----delete系统调用
  • 打开文件----open系统调用
  • 关闭文件----close系统调用

可用几个基本操作完成更复杂的操作,比如:“复制文件”:

  1. 先创建一个新的空文件
  2. 再把源文件读入内存
  3. 再将内存中的数据写到新文件中

文件在外存中的存储方式

与内存相似,磁盘分为若干小磁盘块,将文件数据连续或离散的存入各磁盘块之间

操作系统需要提供的其他文件管理功能

  • 文件共享
  • 文件保护

文件的逻辑结构

本节我们重点关注有结构文件:

由一组相似的记录组成,又称“记录式文件”。每条记录又由若干个数据项组成。如:数据库表文件。一般来说,每条记录有一个数据项可作为关键字(作为识别不同记录的ID)

根据各条记录的长度(占用的存储空间)是否相等,又可分为定长记录变长记录两种。

定长记录↓

可变长记录↓

有结构文件的逻辑结构

**顺序文件:**文件中的记录一个接一个地顺序存储(逻辑上),记录可以是定长的或可变长的。各个记录在物理上可以顺序存储或链式存储。

**索引文件:**建立一张索引表以加快文件检索的速度,每条记录对应一个索引项,记录中的文件在物理上就可以离散地存放

索引表本身是定长记录的顺序文件。因此可以快速找到第i个记录对应的索引项。

可将关键字作为索引号内容,若按关键字顺序排列,则还可以支持按照关键字折半查找。

每当要增加/删除一个记录时,需要对索引表进行修改。由于索引文件有很快的检索速度,因此主要用于对信息处理的及时性要求比较高的场合。

另外,可以用不同的数据项建立多个索引表。如:学生信息表中,可用关键字“学号”建立一张索引表。也可用“姓名”再建立一张索引表。这样就可以根据“姓名”快速地检索文件了。

但这样对存储空间的利用率就会较低

**索引顺序文件:**将索引文件和顺序文件的思想相结合。与索引文件不同的是:并不是每个记录都对应一个索引表项,而是一组记录对应一个索引表项。

左边表是索引表,右边是顺序存储,通过索引找到首字母初地址,再进行顺序查找。

这种存储方式在记录数较少情况下检索速率较快,但记录数多的情形下检索效率依旧不足,所以我们引入多级索引顺序文件👇

文件目录

文件控制块

目录文件----本身就是一种有结构文件,由一条条记录组成。每条记录对应一个放在该目录下的文件👇

目录文件中的一条记录就是一个“文件控制块(FCB)”

FCB的有序集合称为”文件目录“,一个FCB就是一个文件目录项。

FCB中包含了文件的基本信息(文件名、物理地址、逻辑结构等),存取控制信息(是否可读/可写、禁止访问的用户名单等),使用信息(文件的建立时间、修改时间等)。 最重要,最基本的还是文件名、文件存放的物理地址。

FCB实现了文件名和文件之间的映射。使用户(用户程序)可以实现”按名存取“。

需要对目录进行的操作:

  • 搜索
  • 创建文件
  • 删除文件
  • 显示目录
  • 修改目录

目录结构----单级目录结构

实现了按名存取,但是不允许文件重名

目录结构----两级目录结构

允许不同用户的文件名重名

目录结构----多级目录结构(树形目录结构)

很多时候,用户会连续访问同一目录内的多个文件,显然,每次都从根目录开始查找是很低效的,因此可以设置一个“当前目录”。

树形目录结构可以很方便地对文件进行分类,层次结构清晰,也能够更有效地进行文件的管理和保护。但是,树形结构不便于实现文件的共享。为此,提出了**“无环图目录结构”**

目录结构----无环图目录结构

在树形目录结构的基础上,增加一些指向同一节点的有向边,使整个目录成为一个有向无环图。可以更方便地实现多个用户间的文件共享。

可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。

需要为每个结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除结点请求时,只是删除该用户的FCB、并使共享计数器减1,并不会直接删除共享结点。

索引节点(FCB的改进)

原来的FCB表是这个样子👇

但是在查找中,文件名是主键,所以我们考虑将主键以外的信息均存储到另一个地方(索引结点),在FCB表中只保留索引结点指针来指向该位置,提高查找效率(减少启动磁盘块次数)

存放在外存中的索引结点称为“硬盘索引结点”

放入内存则称为“内存索引结点”

文件的物理结构

操作系统需要对磁盘块进行的管理:

  • 对非空闲磁盘块的管理(文件的物理结构/文件分配方式等)
  • 对空闲磁盘块的管理

很多操作系统中,磁盘块的大小与内存块、页面的大小相同

内存与磁盘之间的数据交换都是以“块”为单位进行的,即每次读入一块,或每次写出一块。

文件的逻辑地址可以表示为**(逻辑块号,块内地址)**的形式

文件分配方式----连续分配

物理块号 = 起始块号 + 逻辑块号

连续分配支持顺序访问和直接访问(即随机访问)

读取某个磁盘块时,需要移动磁头。访问的两个磁盘块相隔越远,移动磁头所需时间越长

结论:

  • 连续分配的文件在顺序读/写时速度最快
  • 物理上采用连续分配的文件不方便拓展
  • 存储空间利用率低,会产生难以利用的磁盘碎片(可以用紧凑来处理碎片,但会耗费很大的时间代价

文件分配方式----链接分配----隐式链接

先读起始,然后读一个才能知道下一个块在哪里存,故名隐式

结论:

  • 只支持顺序访问,不支持随机访问
  • 链接分配方式,很方便文件拓展
  • 不会有碎片问题,外存利用率高

文件分配方式----连接分配----显式链接

把用于链接文件各物理块的指针显式地存放在一张表中,即文件分配表(FAT)

逻辑块号转换成物理块号的过程不需要读磁盘操作

结论:

  • 支持顺序访问,也支持随机访问,块号转换过程并不需要访问磁盘,因此相比于隐式链接来说,访问速度快很多
  • 同样不会产生外部碎片,可以很方便地对文件进行拓展
  • 缺点是文件分配表需要占用一定的存储空间

文件分配方式----索引分配

索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。

总结:

  • 可以支持随机访问,文件拓展也很容易实现
  • 缺点是索引表需要占用一定的存储空间
如果索引表太大,一个磁盘块装不下,提供三种解决方案:
  1. 链接方案:如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放 但如果文件太大,索引块太多,使用链接的方式存储,则会导致若要访问最后一个链接块就必须要访问前面的所有逻辑块,这种方式显然很低效

  2. 为了解决上述问题,我们引出多级索引,建立多层索引(类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。

    根据逻辑块号计算表项:

    逻辑块号/索引表长度 = 一级索引块号

    逻辑块号%索引表长度 = 二级索引表中块内偏移量

    文件最大长度 = 索引表长度^索引总层数*内存块大小

    采用K层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要K+1次读磁盘操作

  3. **混合索引:**多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)

文件存储空间管理

存储空间管理----空闲表法

回收时要注意表项的合并问题

存储空间管理----空闲链表法

空闲盘块链

操作系统保存着链头、链尾指针。

**分配:**若某文件申请K个盘块,则从链头开始依次摘下K个盘块分配,并修改空闲链的链头指针。

**回收:**回收的盘块依次挂到链尾,并修改空闲链的链尾指针。

这种分配方式适用于离散分配的物理结构。为文件分配多个盘块时可能要重复多次操作。

空闲盘区链

操作系统保存着链头、链尾指针。

**分配:**若某文件申请K个盘块,则可以采用首次适应、最佳适应算法,从链头开始检索,按照算法规则找到一个大小符合要求的空闲盘区,分配给文件。若没有合适的连续空闲块,也可以将不同盘区的盘块同时分配给一个文件,注意分配后可能要修改相应的链指针、盘区大小等数据。

**回收:**若回收区和某个空闲盘区相邻,则需要将回收区合并到空闲盘区中。若回收区没有和任何空闲区相邻,将回收区作为单独的一个空闲盘区挂到链尾。

离散分配、连续分配都适用。为一个文件分配多个盘块时效率更高。

存储空间管理----位示图法

每个二进制位对应一个盘块,"0"代表盘块空闲,"1"代表盘块已分配。位示图一般用连续的“字”来表示,如本例中一个字的字长是16位,字中的每一位对应一个盘块。因此可以用(字号,位号)对应一个盘块号。

转换计算:(字号,位号)= (i,j)的二进制位对应的盘块号b = ni + j

b号盘块对应的字号i = b/n,位号j = b%n

存储空间管理----成组链接法

空闲表法、空闲链表法不适用于大型文件系统,因为空闲表或空闲链表可能过大。UNIX系统中采用了成组链接法对磁盘空闲块进行管理。

文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。