2021-11-29 《计算机操作系统》(第四版)学习笔记:第七章

第七章 文件管理

7.1 文件和文件系统

7.1.1 数据项记录和文件

(1)数据项

​ 数据项是最低级的数据组织形式,可以分为两种类型:

  1. 基本数据项

    用于描述一个对象的某种属性的字符集,是数据组织中可以命名的最小逻辑数据单位,又称为字段。

    例如,用于描述一个学生的基本数据项有:学号、姓名、年龄、所在班级等。

  2. 组合数据项

    由若干个基本数据项组成,简称组项。

    例如,工资是个组项,它可由基本工资、工龄工资和奖励工资等基本项所组成。

(2)记录

​ 记录是一组相关数据项的集合,用于描述一个对象在某方面的属性。

​ 例如,一个学生的描述可以使用学好、姓名、年龄和所在班级;一个患者的描述可以使用病历号、姓名、性别、出生年月、身高、体重等。

(3)文件

​ 文件是指由创建者所定义的、具有文件名的一组相关元素的集合,可分为有结构文件和无结构文件两种。

​ 在有结构的文件中,文件由若干个相关记录组成。而无结构文件则被看成是一个字符流。

​ 文件在文件系统中是一个最大的数据单位,它描述了一个对象集。例如,可以将一个班的学生记录作为一个文件。

​ 文件属性可以包括∶

  1. 文件类型。

    可以从不同的角度来规定文件的类型,如源文件、目标文件及可执行文件等。

  2. 文件长度。

    文件长度指文件的当前长度,长度的单位可以是字节、字或块,也可能是最大允许的长度。

  3. 文件的物理位置。

    该项属性通常用于指示文件所在的设备及所在设备中地址的指针。

  4. 文件的建立时间。

    这是指最后一次的修改时间等。

7.1.2 文件名和类型

(1)文件名

​ 用于标识不同的文件的名称。

(2)扩展名

​ 添加在文件名后面的若干个附加字符,用于指示文件的类型。

​ 在大多数系统中,使用圆点 “.” 将文件名和扩展名分开,通常长度为 1 ~ 4 个字符。

(3)文件类型

​ 根据不同系统对文件管理的方式不同,对文件分类的方法也有很大差异。

  1. 按用途分类

    • 系统文件

      大多数系统文件只允许用户调用,不允许用户读和修改。

    • 用户文件

      指用户的源代码、目标文件、可执行文件等。

    • 库文件

      由标准子例程及常用的例程所构成的文件。允许用户调用,但不允许修改。

  2. 按文件中数据的形式分类

    • 源文件
    • 目标文件
    • 可执行文件
  3. 按存储控制属性分类

    • 只执行文件
    • 只读文件
    • 读写文件
  4. 按组织形式和处理方式分类

    • 普通文件
    • 目录文件
    • 特殊文件
7.1.3 文件系统的层次结构

​ 文件系统的模型可以分为三个层次:

(1)对象及其属性

​ 文件管理系统管理的对象如下:

  1. 文件
  2. 目录
  3. 磁盘存储空间

(2)对对象操纵和管理的软件集合

​ 该层是文件管理系统的核心部分。一般地,把与文件系统有关的软件分为四个层次:

  1. I/O 控制层

    是文件系统的最低层,主要由磁盘驱动程序等组成。

  2. 基本文件系统层

    主要用于处理内存与磁盘之间数据块的交换

  3. 基本 I/O 管理程序

    用于完成与磁盘 I/O 有关的事务。

  4. 逻辑文件系统

    用于处理与记录和文件相关的操作。

(3)文件系统的接口

​ 通常接口分为两种类型:

(1)命令接口

​ 指作为用户与文件系统直接交互的接口,用户可通过键盘终端键入命令获得文件系统的服务。

(2)程序接口

​ 指作为用户程序与文件系统的接口,用户程序可以通过系统调用取得文件系统的服务。

7.1.4 文件操作

(1)最基本的文件操作

  1. 创建文件
  2. 删除文件
  3. 读文件
  4. 写文件
  5. 设置文件的读写位置

(2)文件的“打开”和“关闭”操作

​ 为了避免多次重复地检索目录,在大多数 OS 中都引入了“打开”这一文件系统调用。当用户第次请求对某文件进行操作时,须先利用 open 系统调用将该文件打开。

​ 所谓“打开”,是指系统将指名文件的属性(包括该文件在外存上的物理位置),从外存拷贝到内存打开文件表的一个表目中,并将该表目的编号(或称为索引号)返回给用户。

​ 换而言之,“打开”,就是在用户和指定文件之间建立起一个连接。此后,用户可通过该连接直接得到文件信息,从而避免了再次通过目录检索文件,即当用户再次向系统发出文件操作请求时, 系统根据用户提供的索引号可以直接在打开文件表中查找到文件信息。这样不仅节省了大量的检索开销,也显著地提高了对文件的操作速度。

​ 如果用户已不再需要对该文件实施相应的操作,可利用“关闭”系统调用来关闭此文件,即断开此连接,OS 将会把该文件从打开文件表中的表目上删除掉。

(3)其他文件操作

​ 最常见的包括:

  1. 有关对文件属性的操作

    包括设置和获得文件的属性,修改文件的拥有者和访问权,查询文件的状态等。

  2. 有关目录的操作

    包括创建和删除目录,改变当前目录和工作目录等。

7.2 文件的逻辑结构

​ 用户看到的文件称为逻辑文件,其由一系列的逻辑记录组成。

​ 系统中所有的文件都存在着以下两种形式的文件结构:

  1. 文件的逻辑结构

    从用户观点出发所观察到的文件组织形式,即文件是由一系列的逻辑记录组成的,是用户可以直接处理的数据及其结构,独立于文件的物理特性。又称为文件组织。

  2. 文件的物理结构

    也称为文件的存储结构。指系统将文件存储在外存上所形成的的一种存储组织形式,是用户不能看见的。

7.2.1 文件逻辑结构的类型

(1)按文件是够有结构分类

  1. 有结构文件
    • 定长记录
    • 变长记录
  2. 无结构文件,即流式文件

(2)按文件的组织方式分类

  1. 顺序文件
  2. 索引文件
  3. 索引顺序文件
7.2.2 顺序文件

(1)顺序文件的排列方式

  1. 串结构

    通常按照存入时间的先后对记录进行排序,每个记录的顺序与关键字无关。

  2. 顺序结构

    由用户指定一个字段作为关键字,按照关键字对记录进行排序。可以使用有效的查找算法来提高检索效率。

(2)顺序文件的优缺点

​ 最佳应用场合:对文件中的记录进行批量存取。

​ 在交互应用的场合中,顺序文件的性能较差,因为需要进行顺序查找。

​ 另外,顺序文件的增添或删除记录操作都比较困难。

7.2.3 记录寻址

(1)隐式寻址方式

定长记录的顺序文件:

​ 在读一个文件时,为了读文件,在系统中应设置一个读指针 Rptr,令它指向下一个记录的首地址,每当读完一个记录时,便执行 Rptr = Rptr + L 操作,使之指向下一个记录的首地址,其中的 L 为记录长度。类似地,为了写文件,也应设置一个写指针 Wptr,使之指向要写的记录的首地址。同样,在每写完一个记录时,又须执行操作:Wptr = Wptr + L。

变长记录的顺序文件:

​ 由于每一条记录 Li 都不一样,因此访问一个指定记录 i,必须扫描或读取前面第 0 ~ i - 1 个记录,访问速度较慢

(2)显示寻址方式

​ 该方式可用于对定长记录的文件实现直接或随机访问。

  1. 通过文件中记录的位置实现随机访问

    记 A 为首地址,L 为每条记录的长度,则:
    A i = A + i × L A_{i}=A+i\times L Ai=A+i×L

  2. 利用关键字实现随机访问

    对目录的检索是基于此方式的,在 [7.3 节](# 7.3 文件目录) 中介绍

7.2.4 索引文件

(1)按关键字建立索引

​ 如果我们为变长记录文件建立一张索引表,为主文件中的每个记录在索引表中分别设置一个表项,记录指向记录的指针(即记录在逻辑地址空间的首址)以及记录的长度 L,索引表按关键字排序,因此其本身也是一个定长记录的顺序文件,这样就把对变长记录顺序文件的顺序检索转变为对定长记录索引文件的随机检索,从而加快对记录检索的速度,实现直接存取。

(2)具有多个索引表的索引文件

​ 根据不同的用户、不同的目的、不同的属性等来建立多个索引表。

7.2.5 索引顺序文件

(1)索引顺序文件的特征

​ 索引顺序文件是对顺序文件的一种改进,它基本上克服了变长记录的顺序文件不能随机访问,以及不便于记录的删除和插入的缺点。但它仍保留了顺序文件的关键特征,即记录是按关键字的顺序组织起来的。它又增加了两个新特征:

  1. 引入了文件索引表,通过该表可以实现对索引顺序文件的随机访问
  2. 增加了溢出文件,用它来记录新增加的、删除的和修改的记录。

​ 索引顺序文件是顺序文件和索引文件相结合的产物,能有效地克服变长记录文件的缺点,而且所付出的代价也不算太大。

(2)索引顺序文件

​ 可以根据情况设置一级或多级索引顺序文件。

7.2.6 直接文件和哈希文件

(1)直接文件

​ 对于直接文件,可以根据给定的关键字直接获得指定记录的物理地址。其关键在于用什么方法进行从记录值到物理地址的转换。

(2)哈希文件

​ 是目前应用最为广泛的一种直接文件,利用 Hash 函数将关键字转换为相应记录的地址。

​ 通常把 Hash 函数作为标准函数存于系统中,供存取文件时调用。

7.3 文件目录

​ 对目录管理的要求如下:

  1. 实现“按名存取”
  2. 提高对目录的检索速度
  3. 文件共享
  4. 允许不同用户的文件重名
7.3.1 文件控制块和索引结点

(1)文件控制块 FCB

​ 通常具有三类信息:

  1. 基本信息类
    • 文件名
    • 文件物理位置
    • 文件逻辑结构
    • 文件物理结构
  2. 存取控制信息类
    • 文件主的存取权限
    • 核准用户的存取权限
    • 一般用户的存取权限
  3. 使用信息类
    • 文件的建立时间
    • 文件上一次修改的事件
    • 当前使用信息

​ 例如,在 MS-DOS 中的文件控制块中,FCB 的长度为 32 个字节,对 360KB 的软盘,总共可包含 112 个 FCB,共占 4 KB 的存储空间。

(2)索引结点

​ 在检索目录文件的过程中,只用到了文件名,而其他信息我们并不需要。因此这些信息在检索目录时并不需要调入内存。

​ 为此,在有的系统中(UNIX),将文件名与文件描述信息分开,使文件描述信息单独形成一个数据结构,称为索引结点。在文件目录中的每个目录项仅由文件名和指向该文件所对应的索引结点的指针构成。

磁盘索引结点包括的内容:

  1. 文件主标识符

  2. 文件类型

  3. 文件存取权限

  4. 文件物理地址

  5. 文件长度

  6. 文件连接计数

    表明在本文件系统中所有指向该文件名的指针计数。

  7. 文件存取时间

struct dinode{
    
    
    short  di_mode;   	      // 文件类型和存取权限 rwx
    short  di_uid;       	  // 文件宿主的用户 id
    char   di_gid;       	  // 文件宿主的组 id
    long   di_size;      	  // 文件大小
    long   di_mtime;    	  // 文件的修改时间
    char   di_nlinks;    	  // 链接数(有多少个文件目录项指向该结点)
    short  di_addr[13];      /* 物理块号,其中:
                                addr[0] ~ addr[9]  直接块号
                                addr[10]  	        一次间接块号
                                addr[11]            二次间接块号 	
                                addr[12]            三次间接块号 */
};

内存索引结点增加的内容:

  1. 内存索引结点编号

  2. 状态

    表示结点是否上锁或被修改。

  3. 访问计数

    每当有一个进程要访问此结点时,访问计数 + 1,访问完成后-1。

  4. 文件所述文件系统的逻辑设备编号

  5. 链接指针

    设置有分别指向空闲链表和散列队列的指针。

struct dinode{
    
    
    short  di_mode;   	      // 文件类型和存取权限 rwx
    short  di_uid;       	  // 文件宿主的用户 id
    char   di_gid;       	  // 文件宿主的组 id
    long   di_size;      	  // 文件大小
    long   di_mtime;    	  // 文件的修改时间
    char   di_nlinks;    	  // 链接数(有多少个文件目录项指向该结点)
    short  di_addr[13];      /* 物理块号,其中:
                                addr[0] ~ addr[9]  直接块号
                                addr[10]  	        一次间接块号
                                addr[11]	        二次间接块号 	
                                addr[12]	        三次间接块号 */
    struct inode  *i_forw;		
    struct inode  *i_back;
    char   i_flag;      	 	/* i 节点是否被修改 */ 
    unsigned int  i_ino;       /* 磁盘 i 节点标志 */
    unsigned int  i_count;     /* 引用计数 */
};
7.3.2 简单的文件目录

(1)单级文件目录

​ 在文件系统中只建立一张目录表:

​ 每当要新建立一个文件时,必须先检索所有的目录项,保证新文件名是唯一的。然后再从目录表中找出一个空白目录项,填入新文件的信息,设置状态位为 1。

  • 优点:简单
  • 缺点:
    • 查找速度慢
    • 不允许重名
    • 不便于实现文件共享

(2)两级文件目录

​ 为了克服单级文件目录所存在的缺点,可以为每一个用户再建立一个单独的用户文件目录 UFD(User File Directory)。这些文件目录具有相似的结构,它由用户所有文件的文件控制块组成。此外,在系统中再建立一个主文件目录 MFD(Master File Directory)。在主文件目录中,每个用户目录文件都占有一个目录项,其目录项中包括用户名和指向该用户目录文件的指针。

  • 优点:

    • 提高了检索目录的速度
    • 在不同的用户目录中国,可以使用相同的文件名
    • 不同用户可以使用不同的文件名访问系统中国的同一个共享文件
  • 缺点:

    将用户隔离开来,不变实现用户之间的共享与合作。

7.3.3 树形结构目录

(1)树形目录

​ 在每个文件目录中,只能有一个根目录。每个文件和每个目录只能有一个父目录。

​ 将数据文件称为树叶,其他的目录均作为树的结点,称为子目录。

​ 其中,用方框代表目录文件,圆圈代表数据文件。

(2)路径名和当前目录

​ 在树形结构目录中,从根目录到任何数据文件都只有一条唯一的通路。在该路径上,从树的根(即主目录)开始,把全部目录文件名与数据文件名依次地用“/”连接起来,即构成该数据文件唯一的路径名。

​ 若每一次访问一个文件时都从根目录开始直到树叶为止,这样非常麻烦并且耗时。为此,可以为每一个进程设置一个“当前目录”,也称为“工作目录”。进程对各个文件的访问都相对于这个目录而进行。

(3)目录操作

  1. 创建目录
  2. 删除目录
    • 不删除非空目录
    • 可删除非空目录
  3. 改变目录
  4. 移动目录
  5. 链接操作
  6. 查找
7.3.4 目录查询技术

​ 目前,对目录进行查询的方式主要有以下两种:

(1)线性检索法

​ 也称顺序检索法。

​ 在单级目录中,利用用户提供的文件名,用顺序查找法直接从文件目录中找到指名文件的目录项。

​ 在树形目录中,用户提供的文件名是由多个文件分量名组成的路径名,此时需对多级目录进行查找。

​ 假定用户给定的文件路径名是 /usr/ast/mbox,则查找 /usr/ast/mbox 文件的过程如下:

  1. 首先,系统先读入第一个文件分量名 usr,找出匹配者,并得到匹配项的索引结点号 6,再从 6 号索引结点中得知 usr 目录文件放在 132 号盘块中,将该盘块内容读入内存。
  2. 其次,系统再将路径名中的第二个分量名 ast 读入,用它与放在 132 号盘块中的第二级目录文件中各目录项的文件名顺序进行比较, 又找到匹配项,从中得到 ast 的目录文件放在 26 号索引结点中,再从 26 号索引结点中得知 /usr/ast 存放在 496 号盘块中,再读入 496 号盘块。
  3. 然后,系统又将该文件的第三分量名 mbox 读入,用它与第三级目录文件 /usr/ast 中各目录项中的文件名进行比较,最后得到 /usr/ast/mbox 的索引结点号为 60,即在 60 号索引结点中存放了指定文件的物理地址。
  4. 目录查询操作到此结束。如果在顺序查找过程中,发现有一个文件分量名未能找到,则应停止查找,并返回“文件未找到”信息。

(2)Hash 方法

​ 如果我们建立了一张 Hash 索引文件目录,便可利用 Hash 方法进行查询,即系统利用用户提供的文件名,并将它变换为文件目录的索引值,再利用该索引值到目录中去查找,这样将显著地提高检索速度。

​ 在处理 Hash 冲突时,一种有效规则是:

  1. 在利用 Hash 法索引查找目录时,如果目录表中相应的目录项是空的,则表示系统中并无指定文件。
  2. 如果目录项中的文件名与指定文件名相匹配,则表示该目录项正是所要寻找的文件所对应的目录项,故而可从中找到该文件所在的物理地址。
  3. 如果在目录表的相应目录项中的文件名与指定文件名并不匹配,则表示发生了“冲突”,此时须将其 Hash 值再加上一个常数(该常数应与目录的长度值互质),形成新的索引值,再返回到第一步重新开始查找。

​ 顺便指出,在现代操作系统中,通常都提供了模式匹配功能,即在文件名中使用了通配符“*”、“?”等。对于使用了通配符的文件名,此时系统便无法利用 Hash 法检索目录,。此时系统还是需要利用线性查找法。

7.4 文件共享

7.4.1 基于有向无循环图实现文件共享

(1)有向无循环图

​ 在严格的树形结构目录中,每个文件只允许有一个父目录,父目录可以有效地拥有该文件,其它用户要想访问它,必须经过其属主目录来访问该文件。这就是说,对文件的共享是不对称的,或者说,树形结构目录是不适合文件共享的。如果允许一个文件可以有多个父目录,即有多个属于不同用户的多个目录,同时指向同一个文件,这样虽会破坏树的特性,但这些用户可用对称的方式实现文件共享,而不必再通过其属主目录来访问。

​ 上图中,允许每一个文件都可以有多个父目录。如图中的文件 F8 有三个父目录,它们分别是 D5、D6 和 D3,其中 D5 和 D3 还使用了相同的名字 p,目录 D6 有两个父目录 D2 和 D1。

(2)利用索引结点

​ 为了解决这个问题,可以引用索引结点,即诸如文件的物理地址及其它的文件属性等信息,不再是放在目录项中,而是放在索引结点中。在文件目录中只设置文件名及指向相应索引结点的指针。

​ 图中的用户 Wang 和 Lee 的文件目录中,都设置有指向共享文件的索引结点指针。此时,由任何用户对共享文件所进行的 Append 操作或修改,都将引起其相应结点内容的改变(例如,增加了新的盘块号和文件长度等),这些改变是其他用户可见的,从而也就能提供给其他用户来共享。

​ 在索引结点中还应有一个链接计数 count,用于表示链接到本索引结点(亦即文件)上的用户目录项的数目。当 count = 3 时,表示有三个用户目录项连接到本文件上,或者说是有三个用户共享此文件。

​ 当用户 C 创建一个新文件时,他便是该文件的所有者,此时将 count 置 1。当有用户 B 要共享此文件时,在用户 B 的目录中增加一目录项,并设置一指针指向该文件的索引结点,此时,文件主仍然是 C,count = 2。

​ 如果用户 C 不再需要此文件,也不能删除该文件。因为,若删除了该文件,也必然删除了该文件的索引结点,这样便会使 B 的指针悬空,而 B 则可能正在此文件上执行写操作,此时将因此半途而废。

7.4.2 利用符号链接实现文件共享

(1)基本思想

​ 允许一个文件或子目录有多个父目录,但其中仅有一个作为主(属主)父目录,其它的几个父目录都是通过符号链接方式与之相链接的(简称链接父目录)。

​ 上图中仅有 D6 指向 F8 的一条实线,另外两条都已成为虚线。这表示 F8 仍然有三个父目录,但只有 D6 才是其主父目录,而 D5 和 D3 都是链接父目录。类似地,D6 的主父目录是 D2,D1 是链接父目录。

​ 这样做的最大好处是,属主结构(用实线连接起来的结构)仍然是简单树,这对文件的删除、 查找等都更为方便。

(2)如何利用符号链实现共享

​ 由系统创建一个 LINK 类型的新文件,也取名为 F,并将 F 写入链接父目录 D5 中,以实现 D5 与文件 F8 的链接。在新文件 F 中只包含被链接文件 F8 的路径名。这样的链接方法被称为符号链接。新文件 F 中的路径名则只被看做是符号链。当用户通过 D5 访问被链接的文件 F8,且正要读 LINK 类型文件时,此要求将被 OS 截获,OS 根据新文件 F 中的路径名去找到文件 F8,然后对它进行读(写),这样就实现了用户 B 对文件 F 的共享。

(3)优缺点

  • 优点
    • 能够链接任何地方的文件
    • 共享文件的其他用户只有该文件的路径名,并不是指针。可以避免删除共享文件后空指针的存在
  • 缺点
    • 共享文件查找开销较大,因为是按照路径名查找
    • 每一个共享文件都存储了多个文件名,在遍历查找时会重复找到该文件

(4)Linux 的两种链接

  • 硬链接 Hard Link(基于索引结点的共享)
  • 软链接 Soft Link(符号链接 Symbolic link)

猜你喜欢

转载自blog.csdn.net/zheliku/article/details/121605595