1、文件的属性

文件名:由创建文件的用户决定文件名,主要是为了方便用户找到了文件,同一目录下允许有重名文件
标识符:一个系统内的各文件标识符唯一,是操作系统用于区分各个文件的一种内部名称。
类型:指明文件的类型。
位置:文件存放的路径、在外存中的地址。
大小:指明文件大小。
保护信息:对文件进行保护的访问控制信息。

2、文件结构分类

无结构文件:文件内部的数据就是一系列二进制流或字符流组成。又称为“流式文件”。
有结构文件:由一组相似的记录组成,又称“记录式文件”。每条记录由若干个数据项组成。每条记录有一个数据项可作为关键字。记录可分为定成记录和变长记录两种。

3、顺序文件

链式存储:无论是定长/变长记录,都无法实现随机存取,每次只能从第一个记录开始以此往后查找。
顺序存储:可变长记录—无法实现随机存取,定长记录—可实现随机存取。

4、索引表

本身是定长记录的顺序文件。因此可以快速找到第i个记录对应的索引项。可将关键字作为索引号内容,若按关键字顺序排列,则还可以支持按照关键字折半查找。每当要增加/删除一个记录时,需要对索引表进行修改。由于索引文件有很快的检索速度,因此主要用于对信息处理的及时性要求比较高的场合。

5、文件的逻辑结构

5.1、无结构文件

由二进制流或字符流组成,无明显的逻辑结构

5.2、有结构文件

由记录组成,分为定长记录、可变长记录;
逻辑结构:顺序文件、索引文件和索引顺序文件

6、文件控制块(FCB)

FCB实现了文件名和文件之间的映射。使用户(用户程序)可以实现“按名存取”。FCB的有序集合称为“文件目录”,一个FCB就是一个文件目录项。FCB包含了文件的基本信息(文件名、物理地址、逻辑结构、物理结构等)。

7、目录结构

7.1、单级目录结构

实现了按名存取,不允许文件重名。一个系统只能有一张目录表,单极目录结构不适合用于多用户操作系统。

7.2、两级目录结构

分为主文件目录用户文件目录
主文件目录:记录用户名及相应用户文件目录的存放位置。
用户目录:由该用户的文件FCB组成。
两级目录结构允许不同用户的文件重名,也可以在目录上实现访问限制。但是两级目录结构依然缺乏灵性,用户不能对自己的文件进行分类。

7.3、多级目录结构(树形目录结构)

方便对文件进行分类,层次结构清晰,也能够有效的进行文件的管理和保护。但是树形结构不便于实现文件的共享
从根目录出发的路径是“绝对路径”
从“当前目录"出发的路径是"相对路径”

7.4、无环图目录结构

可用不同文件名指向同一个文件,甚可以指向同一个目录(共享同一目录下的所有内容)。需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除点的请求时,只是删除该用户的FCB、并使共享计数器减1,并不会直接删除共享结点。当共享计数器减为0时,删除结点。
注意:共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个·用户修改了文件数据,那么所有用户都可以看到文件数据的变化。

8、索引结点

  1. 除了文件名之外的所有信息都放到索引结点中,每个文件对应一个索引结点
  2. 目录项中只包含文件名、索引结点指针,因此每个目录项的长度大幅减小
  3. 由于目录项长度减小,因此每个磁盘块可以存放更多个目录项,因此检索文件时磁盘!/O的次数就少了很多

9、文件的物理结构

文件分配方式
顺序分配:文件分配的必须是连续的磁盘块。优点:顺序存取速度快,支持随机访问。缺点:会产生碎片,不利于文件拓展。
链式分配:链接分配采取离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种。

  1. 隐式链接一一除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针。优点:很方便文件拓展,不会有碎片问题,外存利用率高。缺点:只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量。
  2. 显式链接一一把用于链接文件各物理块的指针显式地存放在一张表中,即文件分配表(FAT,FileAllocation Table)。一个磁盘只会建立一张文件分配表。开机时文件分配表放入内存,并常驻内存
    优点:很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接地址转换时不需要访问磁盘,因此文件的访问效率更高。
    缺点:文件分配表的需要占用一定的存储空间。

索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块(索引表的功能类似于内存管理中的页表一一建立逻辑页面到物理页之间的映射关系)。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。若文件太大,索引表项太多,可以采取以下三种方法解决:

  1. 链接方案:如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。缺点:若文件很大,索引表很长,就需要将很多个索引块链接起来。想要找到i号索引块,必须先依次读入0~i-1号索引块,这就导致磁盘/O次数过多,查找效率低下。
  2. 多层索引:建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。采用K层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要K+1次读磁盘操作。缺点:即使是小文件,访问一个数据块依然需要K+1次读磁盘。
  3. 混合索引:多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。
    优点:对于小文件来说,访问一个数据块所需的读磁盘次数更少。

10、文件存储空间管理

10.1、存储空间的划分与初始化

  1. 文件卷(逻辑卷)的概念:将物理磁盘划分一个个文件卷
  2. 目录区:主要存放文件目录信息(FCB)、用与磁盘存储空间管理的信息
  3. 文件区:用于存放文件数据
  4. 存储空间的初始化:将各个文件卷划分为目录区、文件区

10.2、存储空间管理

如何分配磁盘块:与内存管理中的动态分区分配很类似,为一个文件分配连续的存储空间。同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。
如何回收磁盘块:与内存管理中的动态分区分配很类似,当回收某个存储区时需要有四种情况一一1回收区的前后都没有相邻空闲区;2回收区的前后都是空闲区;3回收区前面是空闲区;4回收区后面是
空闲区。总之,回收时需要注意表项的合并问题

10.2.1、空闲表法

原理:维护一张空闲表,每个表项记录一个连续空闲盘区:起始块号 + 空闲块数量。和内存的动态分区空闲表思路一样。
分配:首次适应 / 最佳适应,找足够大的连续空闲区,划分出需要的块,修改表项;
回收:归还盘块,检查能否和前后空闲区合并,修改 / 新增表项。
特点:适合连续分配;碎片多的时候表会很大;离散文件效率差。

10.2.2、空闲链表法(分为空闲盘块链、空闲盘区链)

  1. 空闲盘块链
    原理:把每一个空闲盘块,用指针串成链表。操作系统保存头指针、尾指针。
    分配:从链表头部依次摘下盘块给文件;
    回收:把归还的盘块插到链表尾部。
    特点:实现简单;每次分配回收只能操作 1 个块;要频繁读磁盘链表块,开销大。
  2. 空闲盘区链
    原理:以连续的空闲盘区为链表结点,每个结点记录:本盘区起始块号、块数、下一个盘区指针。
    分配:找长度足够的空闲盘区,可以分配连续多个块;
    回收:归还盘块,判断是否可以和前后盘区合并,再链入链表。
    特点:连续、离散文件都适配;合并操作增加开销。

10.2.3、位示图法

原理:用二进制位图,1 位代表 1 个磁盘块。0=空闲,1=已分配。
位示图存放在内存,通过字号、位号换算得到磁盘块号。
分配:遍历位图找连续为 0 的位,标记为 1,算出对应块号;
回收:把对应位清零。
特点:占用空间小,速度快;广泛使用;需要计算块号;要常驻内存。

10.2.4、 成组链接法(UNIX/Linux 经典)

原理:把空闲盘块分组。超级块保存第一组的空闲块计数和块号;每组最后一个盘块保存下一组的全部块号信息,形成链式分组。
分配:从超级块取出块号分配;组内耗尽,就把下一组的内容读到超级块。
回收:盘块回收到当前组;组满了,把当前组信息写入新回收块,超级块切换为新组。
特点:结合链表 + 栈思想;超级块在内存,大部分操作不用读磁盘;速度高;是 UNIX 系统采用的方案。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐