【操作系统】文件管理
文件与文件系统
文件则是指具有文件名的若干相关元素的集合,元素通常是记录,而记录又是一组有意义的数据项的集合。文件系统的管理功能,是通过把它所管理的程序和数据组织成一系列文件的方法来实现的。
在文件系统中,数据项是最低级的数据组织形式,有两种:基本数据项(用于描述一个对象的某种属性的字符集,是数据组织中可以命名的最小逻辑数据单位,即原子数据,又称为数据元素或字段。例如,用于描述一个学生的基本数据项有学号、姓名、年龄、所在班级等。)、组合数据项(由若干个基本数据项组成的,简称组项。例如,经理便是个组项,它由正经理和副经理两个基本项组成。)
记录是相关数据项的集合,用于描述一个对象在某方面的属性。例如,一个学生,当把他作为班上的一名学生时,对他的描述应使用学号、姓名、年龄及所在系班,也可能还包括他所学过的课程的名称、成绩等数据项。在诸多记录中,为了能惟一地标识一个记录,必须在一个记录的各个数据项中,确定出一个或几个数据项,把它们的集合称为关键字(key)。
文件是指由创建者所定义的、具有文件名的一组相关元素的集合,可分为有结构文件和无结构文件两种。在有结构的文件中,文件由若干个相关记录组成,又称为记录式文件;而无结构文件则被看成是一个字符流,又称流式文件。文件在文件系统中是一个最大的数据单位,它描述了一个对象集。文件应具有自己的属性,如文件类型、文件长度、文件物理位置、文件建立时间等。
特殊文件:特指系统中的各类I/O 设备。为了便于统一管理,系统将所有的输入/输出设备都视为文件,按文件方式提供给用户使用,如目录的检索、权限的验证等都与普通文件相似,只是对这些文件的操作是和设备驱动程序紧密相连的,系统将这些操作转为对具体设备的操作。根据设备数据交换单位的不同,又可将特殊文件分为块设备文件和字符设备文件。
文件系统模型其最底层是对象及其属性,中间层是对对象进行操纵和管理的软件集合,最高层是文件系统提供给用户的接口。对象及其属性有文件、目录、磁盘存储空间等。对对象操纵和管理的软件集合是文件管理系统的核心部分,其中包括: 对文件存储空间的管理、对文件目录的管理、用于将文件的逻辑地址转换为物理地址的机制、对文件读和写的管理,以及对文件的共享与保护等功能。文件系统的接口为有命令接口(指作为用户与文件系统交互的接口。用户可通过键盘终端键入命令,取得文件系统的服务。)和程序接口(系统调用)。
最基本的文件操作有: 创建文件、删除文件、读文件、写文件、截断文件和设置文件的读/写位置。
- 创建文件:分配外存空间,在文件系统中建立目录项(记录文件名,外存地址等属性)。
- 删除文件:删除目录项,回收存储空间。
- 读文件:在读一个文件时,须在相应系统调用中给出文件名和应读入的内存目标地址。
- 写文件:在写一个文件时,须在相应系统调用中给出该文件名及该文件在内存中的(源)地址。
- 截断文件:一种是删除原文件,创建新文件;另一种是放弃文件中的内容。
- 设置文件读写位置:用于设置文件读/写指针的位置。
文件操作过程大致都是这样两步: 第一步是通过检索文件目录来找到指定文件的属性及其在外存上的位置;第二步是对文件实施相应的操作,如读文件或写文件等。当用户要求对一个文件实施多次读/写或其它操作时,每次都要从检索目录开始。为了避免多次重复地检索目录,在大多数OS中都引入了“打开”(open)这一文件系统调用,当用户第一次请求对某文件进行操作时,先利用open系统调用将该文件打开。所谓“打开”,是指系统将指名文件的属性(包括该文件在外存上的物理位置)从外存拷贝到内存打开文件表的一个表目中,并将该表目的编号(或称为索引)返回给用户。以后,当用户再要求对该文件进行相应的操作时,便可利用系统所返回的索引号向系统提出操作请求。系统这时便可直接利用该索引号到打开文件表中去查找,从而避免了对该文件的再次检索。这样不仅节省了大量的检索开销,也显著地提高了对文件的操作速度。如果用户已不再需要对该文件实施相应的操作时,可利用“关闭”(close)系统调用来关闭此文件,OS将会把该文件从打开文件表中的表目上删除掉。
文件的逻辑结构
文件的物理结构,又称为文件的存储结构,是指文件在外存上的存储组织形式。这不仅与存储介质的存储性能有关,而且与所采用的外存分配方式有关。
文件的逻辑结构是从用户观点出发所观察到的文件组织形式,是用户可以直接处理的数据及其结构,它独立于文件的物理特性,又称为文件组织。文件逻辑结构的基本要求是提高检索速度、便于修改、降低文件存储费用。按记录的可分为定长记录和变长记录。文件可分为有结构文件和无结构文件,有结构文件顺序文件、索引文件、索引顺序文件。无结构文件如源程序、可执行文件、库函数等,即流式文件。在UNIX 系统中,所有的文件都被看做是流式文件,即使是有结构文件,也被视为流式文件,系统不对文件进行格式处理。
直接文件可根据给定的记录键值,直接获得指定记录的物理地址。换言之,记录键值本身就决定了记录的物理地址。哈希文件目前应用最为广泛的一种直接文件。它利用Hash 函数(或称散列函数),可将记录键值转换为相应记录的地址。但为了能实现文件存储空间的动态分配,通常由Hash函数所求得的并非是相应记录的地址,而是指向一目录表相应表目的指针,该表目的内容指向相应记录所在的物理块。
外存分配方式
常用的外存分配方法有连续分配、链接分配和索引分配三种。文件的物理结构直接与外存分配方式有关。在采用不同的分配方式时,将形成不同的文件物理结构。例如,在采用连续分配方式时的文件物理结构,将是顺序式的文件结构;链接分配方式将形成链接式文件结构;而索引分配方式则将形成索引式文件结构。
连续分配要求为每一个文件分配一组相邻接的盘块。优点是顺序访问容易,访问速度快;缺点是要有连续存储空间,需要事先知道文件长度。
链接分配方式可通过在每个盘块上的链接指针,将同属于一个文件的多个离散的盘块链接成一个链表,把这样形成的物理文件称为链接文件。链接方式又可分为隐式链接和显式链接两种形式。隐式链接分配方式在文件目录的每个目录项中,都须含有指向链接文件第一个盘块和最后一个盘块的指针。
显示链接把用于链接文件各物理块的指针,显式地存放在内存的一张链接表中。该表在整个磁盘仅设置一张。
索引分配它为每个文件分配一个索引块(表),再把分配给该文件的所有盘块号都记录在该索引块中,因而该索引块就是一个含有许多盘块号的数组。在打开某个文件时,只需把该文件占用的盘块的编号调入内存即可,完全没有必要将整个FAT 调入内存。当 OS为一个大文件分配磁盘空间时,如果所分配出去的盘块的盘块号已经装满一个索引块时,OS便为该文件分配另一个索引块,用于将以后继续为之分配的盘块号记录于其中。依此类推,再通过链指针将各索引块按序链接起来。或者采用多级索引,即为索引块再建立索引。
目录管理
文件目录也是一种数据结构,用于标识系统中的文件及其物理地址,供检索时使用。文件目录的要求:1、实现“按名存取”;2、提高对目录的检索速度;3、文件共享;4、允许文件重名。为了能对一个文件进行正确的存取,必须为文件设置用于描述和控制文件的数据结构,称之为“文件控制块(FCB)”。文件管理程序可借助于文件控制块中的信息,对文件施以各种操作。文件与文件控制块一一对应,而人们把文件控制块的有序集合称为文件目录,即一个文件控制块就是一个文件目录项。通常,一个文件目录也被看做是一个文件,称为目录文件。在文件控制块中,通常应含有三类信息,即基本信息(① 文件名② 文件物理位置③ 文件逻辑结构④ 文件的物理结构)、存取控制信息(文件主的存取权限、核准用户的存取权限以及一般用户的存取权限。)及使用信息(文件的建立日期和时间、文件上一次修改的日期和时间及当前使用信息)。
在检索目录文件的过程中,只用到了文件名,仅当找到一个目录项(即其中的文件名与指定要查找的文件名相匹配)时,才需从该目录项中读出该文件的物理地址。而其它一些对该文件进行描述的信息,在检索目录时一概不用。显然,这些信息在检索目录时不需调入内存。为此,在有的系统中,如UNIX 系统,便采用了把文件名与文件描述信息分开的办法,亦即,使文件描述信息单独形成一个称为索引结点的数据结构,简称为i结点。在文件目录中的每个目录项仅由文件名和指向该文件所对应的i 结点的指针所构成。
目录的组织结构,关系到文件系统的存取速度,也关系到文件的共享性和安全性。目前常用的目录结构形式有单级目录、两级目录和多级目录。
单级目录结构在整个文件系统中只建立一张目录表,每个文件占一个目录项,目录项中含文件名、文件扩展名、文件长度、文件类型、文件物理地址以及其它文件属性,此外,为表明每个目录项是否空闲,又设置了一个状态位。需保证文件名唯一。优点是按名存取;缺点是查找速度慢,不允许重名,不便于共享文件。
两级目录结构为每一个用户建立一个单独的用户文件目录。 优点提高了检索速度,不同用户可以使用相同文件名,可以共享文件。
对于大型文件系统,通常采用三级或三级以上的目录结构,以提高对目录的检索速度和文件系统的性能。多级目录结构又称为树型目录结构,主目录在这里被称为根目录,把数据文件称为树叶,其它的目录均作为树的结点。在树形目录结构中,从根目录到任何数据文件,都只有一条惟一的通路。在该路径上从树的根(即主目录)开始,把全部目录文件名与数据文件名依次地用“/”连接起来,即构成该数据文件的路径名。系统中的每一个文件都有惟一的路径名。把从当前目录开始直到数据文件为止所构成的路径名,称为相对路径名;而把从树根开始的路径名称为绝对路径名。
当用户要访问一个已存在文件时,系统首先利用用户提供的文件名对目录进行查询,找出该文件的文件控制块或对应索引结点;然后,根据FCB 或索引结点中所记录的文件物理地址(盘块号),换算出文件在磁盘上的物理位置;最后,再通过磁盘驱动程序,将所需文件读入内存。目前对目录进行查询的方式有两种: 线性检索法和Hash方法。
文件存储空间的管理
如何为新创建的文件分配存储空间。其分配方法与内存的分配有许多相似之处,即同样可采取连续分配方式或离散分配方式。前者具有较高的文件访问速度,但可能产生较多的外存零头;后者能有效地利用外存空间,但访问速度较慢。不论哪种分配方式,存储空间的基本分配单位都是磁盘块而非字节。为了实现存储空间的分配,系统首先必须能记住存储空间的使用情况。为此,系统应为分配存储空间而设置相应的数据结构;其次,系统应提供对存储空间进行分配和回收的手段。
空闲表法和空闲链表法
空闲表法属于连续分配方式,它的分配和回收与内存的动态分配和回收方式相似。空闲链表法是将所有空闲盘区拉成一条空闲链。根据构成链所用基本元素的不同,可把链表分成两种形式:空闲盘块链和空闲盘区链。
位示图法
位示图是利用二进制的一位来表示磁盘中一个盘块的使用情况。当其值为“0”时,表示对应的盘块空闲;为“1”时,表示已分配。分配:1、顺序扫描位示图,从中找出一个或一组其值为“0”的二进制位;2、将所找到的一个或一组二进制位转换成与之相应的盘块号。假定找到的其值为“0”的二进制位位于位示图的第i 行、第j列,则其相应的盘块号应按下式计算:b = n(i - 1) + j,其中n为每行位数;3、修改位示图,map[i,j]=1。回收:1、将回收盘块的盘块号转换成位示图中的行号和列号。转换公式为:i = (b - 1)DIV n + 1,j = (b - 1)MOD n + 1;2、修改位示图。令map[i,j] =0。
成组链接法
空闲表法和空闲链表法都不适用于大型文件系统,因为这会使空闲表或空闲链表太长。在UNIX 系统中采用的是成组链接法,这是将上述两种方法相结合而形成的一种空闲盘块管理方法。
文件共享和保护
基于索引结点的共享方式
基于符号链共享方式:为使B能共享C的一个文件F,可以由系统创建一个LINK 类型的新文件,也取名为F,将F写入B的目录中,以实现B的目录与文件F的链接。在新文件中只包含被链接文件F的路径名。这样的链接方法被称为符号链接。新文件中的路径名则只被看作是符号链,当B要访问被链接的文件F且正要读LINK 类新文件时,此要求将被OS 截获,OS 根据新文件中的路径名去读该文件,于是就实现了用户B 对文件F的共享。
在利用符号链方式实现文件共享时,只是文件主才拥有指向其索引结点的指针;而共享该文件的其他用户则只有该文件的路径名,并不拥有指向其索引结点的指针。这样,也就不会发生在文件主删除一共享文件后留下一悬空指针的情况。当文件的拥有者把一个共享文件删除后,其他用户试图通过符号链去访问一个已被删除的共享文件时,会因系统找不到该文件而使访问失败,于是再将符号链删除,此时不会产生任何影响。
数据一致性控制
参考
《计算机操作系统》 第三版 汤小丹