【操作系统】 文件管理

文件系统基础

文件是以计算机硬盘为载体的存储在计算机上的信息集合。在系统运行时,计算机以进程为基本单位进行资源的调度和分配;而在用户进行的输入、输出中,则以文件为基本单位。

 

文件的基本操作:

  1. 创建文件。创建文件有两个必要步骤:一是在文件系统中为文件找到空间;二是在目录中为新文件创建条目,该条目记录文件名称、在文件系统中的位置及其他可能的信息。
  2. 写文件。为了写文件,执行一个系统调用,指明文件名称和要写入文件的内容。对于给定文件名称,系统搜索目录可以查找文件位置。系统必须为该文件维护一个写位置的指针。每当发生写操作时,便更新写指针。
  3. 读文件。为了读文件,执行一个系统调用,指明文件名称和要读入文件块的内存位置。同样,需要搜索目录以找到相关目录项,系统维护一个读位置的指针。每当发生读操作时,更新读指针。一个进程通常只对一个文件读或写,因此当前操作位置可作为每个进程当前文件位置的指针。由于读和写都使用同一指针,因此节省了空间,也降低了系统的复杂性。
  4. 文件重定位(文件寻址)。按某条件搜索目录,将当前文件位置设为给定值,并且不会读、写文件。
  5. 删除文件。先从目录中找到要删除文件的目录项,使之成为空项,然后回收该文件所占用的存储空间。
  6. 截断文件。允许文件所有属性不变,并删除文件内容,即将其长度设为0并释放其空间。

这6个基本操作可以组合起来执行其他文件操作。例如文件的复制。

 

 

按逻辑结构,文件可以划分为无结构文件和有结构文件两种。

 

无结构文件(流式文件)

 

无结构文件是最简单的文件组织形式。无结构文件将数据按照顺序组织并积累、保存,它是有序相关信息项的集合,以字节为单位。由于无结构文件没有结构,因而对记录的访问只能通过穷举搜索的方式,故这种文件形式对大多数应用不适用。但字符流的无结构文件管理简单,用户可以方便地对其进行操作。所以,对那些基本信息单位操作不多的文件比较适于采用字符流的无结构方式,如源程序文件、目标代码文件等。

 

有结构文件(记录式文件)

 

有结构文件按记录的组织形式可以分为如下几种:

 

  1. 顺序文件。文件中的记录一个接一个地顺序排列,记录通常是定长的,可以顺序存储或以链表的形式存储,在访问时需要顺序搜索文件。
  2. 索引文件。对于定长记录文件,要查找第 i 条记录,可直接根据下式计算得到第 i 条记录相对于第一条记录的地址:Ai = i * L,对于可变长记录的文件,要查找第 i 条记录,必须顺序地查找前 i - 1 条记录。
  3. 索引顺序文件。是顺序和索引两种组织形式的结合。索引顺序文件将顺序文件中的所有记录分为若干组,为顺序文件建立一张索引表,在索引表中为每组中的第一条记录建立一个索引项,其中含有该记录的关键字值和指向该记录的指针。N 条记录分为 √N 组,索引表中有 √N 个表项,每组有 √N 条记录,平均需查找 √N 次。
  4. 直接文件或散列文件(Hash File)给定记录的键值或通过散列函数转换的键值直接决定记录的物理地址。这种映射结构不同于顺序文件或索引文件,没有顺序的特性。散列文件有很高的存取速度,但是会引起冲突,即不同关键字的散列函数值相同。

 

变长记录只能顺序查找,系统开销较大。为此,可以建立一张索引表以加快检索速度,索引表本身是定长记录的顺序文件。在记录很多或访问要求高的文件中,需要引入索引以提供有效的访问。实际中,通过索引可以成百上千倍地提高访问速度。

 

 

文件控制块(FCB)是用来存放控制文件需要的各种信息的数据结构,以实现“按名存取”。FCB的有序集合称为文件目录,一个 FCB 就是一个文件目录项。为了创建一个新文件,系统将分配一个 FCB 并存放在文件目录中,成为目录项。FCB必须连续存放

在检索目录的过程中,只用到了文件名,仅当找到一个目录项(查找文件名与目录项中文件名匹配)时,才需要从该目录项中读出该文件的地址,也就是说,在检索目录时,文件的其他描述信息不会用到,也不需要调入内存。因此,有的系统(如 UNIX)采用了文件名和文件描述信息分开的方法,文件描述信息单独形成一个称为索引节点的数据结构,简称 i 结点。在文件目录中的每个目录项仅由文件名和指向该文件所对应的 i 结点的指针构成。

 

在目录层次上所需要执行的操作:

  • 搜索。当用户使用一个文件时,需要搜索目录,以找到该文件的对应目录项。
  • 创建文件,当创建一个新文件时,需要在目录中增加一个目录项。
  • 删除文件。当删除一个文件时,需要在目录中删除相应的目录项。
  • 显示目录。用户可以请求显示目录内容,如显示该目录中的所有文件及属性。
  • 修改目录。某些文件属性保存在目录中,因而这些属性的变化需要改变相应的目录项。

 

目录结构:

  1. 单级目录结构。在整个文件系统中只建立一张目录表,每个文件占一个目录项。不能重名。
  2. 两级目录结构。将文件目录分为主文件目录和用户文件目录。可以解决多用户之间的文件重名问题,不能对文件分类。
  3. 多级目录结构(树形目录结构)。将两级目录结构的层次关系加以推广,就形成了多级目录结构。从根地址出发的路径称为绝对路径。进程对各文件的访问都是相对于当前目录进行的
  4. 无环图目录结构。树形目录能便于实现文件分类,但不便于实现文件共享,为此在树形目录结构的基础上增加了一些指向同一结点的有向边,使整个目录成为一个有向无环图。引入无环图目录结构是为了实现文件共享。

 

文件共享使多个用户共享同一个文件,系统中只需保留该文件的一个副本。若系统不能提供共享功能,则每个需要该文件的用户都要有各自的副本,会造成对存储空间的极大浪费。

 

现代常用的两种文件共享方法如下:

  1. 基于索引结点的共享方式(硬链接)。在树形结构的目录中,当有两个或多个用户要共享一个子目录或文件时,必须将共享文件或子目录连接到两个或多个用户的目录中,才能方便地找到该文件。在这种共享方式中,诸如文件的物理地址及其他的文件属性等信息,不再放在目录项中,而放在索引结点中。在文件目录中只设置文件名及指向相应索引结点的指针。在索引结点中还应有一个链接计数 count,用于表示链接到本索引结点(即文件)上的用户目录项的数目。当 count = 2 时,表示有两个用户目录项链接到本文件上,或者说有两个文件共享此文件。当 count = 0 时,表示没有用户使用该文件,系统将负责删除该文件。
  2. 利用符号链实现文件共享(软链接)。为使用户 B 能共享用户 A 的一个文件 F,可以由系统创建一个 LINK 类型的新文件,也取名为 F,并将文件 F 写入用户 B 的目录中,以实现用户 B 的目录与文件 F 的链接。在新文件中只包含被链接文件 F 的路径名,这样的链接方法被称为符号链接。(快捷方式)

 

文件保护通过口令保护、加密保护和访问控制等方式实现。其中,口令保护和加密保护是为了防止用户文件被他人存取或窃取,没有控制用户对文件访问类型,而访问控制则用于控制用户对文件的访问方式。

 

解决访问控制最常用的方法是根据用户身份进行控制。而实现基于身份访问的最为普通的方法是,为每个文件和目录增加一个访问控制列表,以规定每个用户名及其所允许访问的类型。

口令和密码是另外两种访问控制方法。

口令指用户在建立一个文件时提供一个口令,系统为其建立 FCB 时附上相应口令,同时告诉允许共享该文件的其他用户。用户请求访问时必须提供相应的口令。这种方法时间和空间的开销不多,缺点是口令直接存在系统内部,不够安全。

密码指用户对文件进行加密,文件被访问时需要使用密钥。这种方法保密性强,节省了存储空间,不过编码和译码要花费一定的时间。

 

索引项只包含每条记录的长度和在逻辑文件中的起始位置。

 当所读文件的数据不在内存时,产生中断(缺页中断),原进程进入阻塞态,直到所需数据从外存调入内存后,才将该进程唤醒。read 系统调用通过陷入将 CPU 从用户态切换到核心态,从而获取操作系统提供的服务。要读一个文件,首先要用 open 系统调用打开该文件。open 中的参数包含文件的路径名与文件名,而 read 只需使用 open 返回的文件描述符,并不使用文件名作为参数。read 要求用户提供三个输入参数:(1)文件描述符 fd;(2)buf 缓冲区首址(3)传送字节数 n。read 的功能是试图从 fd 所指示的文件中读入 n 个字节的数据,并将它们送至指针 buf 所指示的缓冲区中。

对一个文件的访问,常由用户访问权限和文件属性共同控制。

一个文件在物理存储器上有一个索引结点号。存在多个文件名指向同一个索引结点的情况。

一个文件被用户进程首次打开即被执行了 open 操作,会把文件的 FCB 调入内存,而不会把文件内容读到内存中,只有进程希望获取文件内容时才会读入文件内容。

 

文件系统实现

文件系统层次结构

 

  1. 用户调用接口。文件系统为用户提供与文件及目录有关的调用,如新建、打开、读写、关闭、删除文件,建立、删除目录等。此层由若干程序模块组成,每个模块对应一条系统调用,用户发出系统调用时,控制即转入相应模块。
  2. 文件目录系统。主要功能是管理文件目录,其任务有管理活跃文件目录表、管理读写状态信息表、管理用户进程的打开文件表、管理与组织存储设备上的文件目录结构、调用下一级存取控制模块。
  3. 存取控制验证。实现文件保护主要由该级软件完成,它把用户的访问要求与 FCB 中指示的访问控制权限进行比较,以确认访问的合法性。
  4. 逻辑文件与文件信息缓冲区。主要功能是根据文件的逻辑结构将用户要读写的逻辑记录抓换成文件逻辑结构内的相应块号。
  5. 物理文件系统。主要功能是把逻辑记录所在的相应块号转换成实际的物理地址。
  6. 辅助分配模块。主要功能是管理辅存空间,即负责分配辅存空闲空间和回收辅存空间。
  7. 设备管理程序模块。主要功能是分配设备、分配设备读写用的缓冲区、磁盘调度、启动设备、处理设备中断、释放设备读写缓冲区、释放设备等。

 

目录实现的基本方法有线性列表和哈希表两种,目录的实现就是为了查找,因此线性列表实现对应线性查找,哈希表的实现对应散列查找。

 

文件分配对应于文件的物理结构,是指如何为文件分配磁盘块。常用的磁盘空间分配方法有三种:连续分配、链接分配和索引分配。

  1. 连续分配。连续分配方法要求每个文件在磁盘上占有一组连续的块,磁盘地址定义了磁盘上的一个线性序列。这种排序使作业访问磁盘时需要的寻道数和寻道时间最小。
  2. 链接分配。链接分配采用离散分配的方式,消除了外部碎片,因此显著提高了磁盘空间的利用率;又因为根据文件的当前需求为其分配必需的盘块,当文件动态增长时,可以动态地再为它分配盘块,因此无须事先知道文件的大小。链接分配又分为隐式链接和显示链接两种形式。(1)隐式链接每个文件对应一个磁盘块的链表;磁盘块分布在磁盘的任何地方,除最后一个盘块外,每个盘块都有 指向下一个盘块的指针,这些指针对用户时透明的(不可见)。目录包括文件第一块的指针和最后一块的指针。隐式链接分配的缺点是无法直接访问盘块,只能通过指针顺序访问文件,且盘块指针会消耗一定的存储空间。隐式链接分配的稳定性也是一个问题,系统在运行过程中由于软件或硬件错误导致链表中的指针丢失或损坏,会导致文件数据的丢失。(2)显示链接是指把用于链接文件各物理块的指针从每个物理块的末尾提取出来,显示地存放在内存的一张链表中。该表在整个磁盘仅设置一张,每个表项中存放对应块的下一块链接指针,即下一个盘块号。由于查找是在内存中进行的,因而不仅显著地提高了检索速度,而且大大减少了访问磁盘的次数。由于分配给文件地所有盘块号都放在该表中,故称该表为文件分配表(File Allocation Table,FAT)。
  3. 索引分配。索引分配把每个文件地所有盘块号都集中放在一起构成索引块(表)。

索引块的索引分配方式:

  • 链接方案。一个索引块通常为一个磁盘块,因此它本身能读写。为了处理大文件,可以将多个索引块链接起来。
  • 多层索引。多层索引使第一层索引块指向第二层的索引块,第二层的索引块再指向文件块。这种方法根据大文件大小的要求,可以继续到第三层或第四层。
  • 混合索引。将多种索引分配相结合的分配方式。例如,系统既采用直接地址,又采用单级索引分配方式或两级索引分配方式。

 

文件存储管理

  1. 空闲表法。空闲表法属于连续分配方式,为每个文件分配一块连续的存储空间。系统为外存上的所有空闲区建立一张空闲盘快表,每个空闲区对应于一个空闲表项,其中包括表项序号、该空闲区第一个盘块号、该区的空闲盘块数等信息。
  2. 空闲链表法。将所有盘区拉成一条空闲链,根据构成链所用的基本元素不同,可把链表分成两种形式:空闲盘块链和空闲盘区链。
  3. 位示图法。位示图利用二进制的一位来表示磁盘中的一个盘块的使用情况,磁盘上所有的盘块都有一个二进制位与之对应。当其值为“0”时,表示对应的盘块空闲;当其值为“1”时,表示对应的盘块已分配。
  4. 成组链接法。大致思想是:把顺序的 n 个空闲扇区地址保存在第一个空闲扇区内,其后一个空闲扇区内则保存另一顺序空闲扇区的地址,如此连续,直至所有空闲扇区均予以链接。表示文件存储器空闲空间的“位向量”表或第一个成组链块,以及卷中的目录区、文件区划分信息都需要存放在辅存储器中,一般放在卷头位置,在 UNIX 系统中称为超级块。

空闲表法和空闲链表法都不适用于大型文件系统,因为这会使空闲表或空闲链表太大。

 

位示图 map[ i , j ]:

i = ( b - 1 ) / n + 1 

j = ( b - 1 ) % n + 1

n代表每行的位数,b是盘块号( i , j 从 1 开始编码)

 

磁盘组织与管理

磁盘通过一个称为磁头的导体线圈从磁盘存取数据。在读 / 写 操作期间,磁头固定,磁盘在下面高速旋转。磁盘盘面上的数据存储在一组同心圆中,称为磁道。每个磁道与磁头一样宽,一个盘面有上千个磁道。磁道又划分为几百个扇区,每个扇区固定存储大小(通常为 512B ),一个扇区称为一个盘块。磁盘的存储能力受限于最内道的最大记录密度。扇区是磁盘可寻址的最小存储单位。

 

一次磁盘读写操作的时间由寻找(寻道)时间、延迟时间和传输时间决定。

      ( 1 )寻找时间 Ts。将磁头移动到指定磁道所需要的时间。这个时间除跨越 n 条磁道的时间外,还包括启动磁臂的时间 s,即 Ts = m * n + s

        ( 2 )   延迟时间 Tr。磁头定位到某一磁道的扇区(块号)所需要的时间,设磁盘的旋转速度为 r ,则 Tr = 1 / ( 2r )

        ( 3 )   传输时间 Tt。从磁盘读出或向磁盘写入数据所经历的时间,这个时间取决于每次所 读 / 写 的字节数 b 和磁盘旋转速度, Tt = b / ( rN ) 式中 N 为一个磁道上的字节数

 

磁盘调度算法(减少寻道时间)

  1. 先来先服务(FCFS)算法。根据进程请求访问磁盘的先后顺序进行调度。
  2. 最短寻找时间优先(SSTF)算法。与当前磁头所在磁道最近的磁道。
  3. 扫描(SCAN)算法(又称电梯调度算法)。在磁头当前移动方向上选择与磁头所在磁道距离最近的请求作为下一次服务的对象,实际上就是在最短寻道优先算法的基础上规定了磁头的移动方向。
  4. 循环扫描(C-SCAN)算法。在扫描算法的基础上固定磁头单向移动来提供服务,回返时直接快速移动至起始端而不服务任何请求。

 

减少延迟时间:对盘面扇区进行交替编号,对磁片组中的不同盘面错位命名。

 

一个新的磁盘只是一个含有磁性记录材料空白盘。在磁盘能存储数据之前,它必须分成扇区以便磁盘控制器能进行读和写操作,这个过程称为低级格式化(物理分区)。逻辑格式化:操作系统将初始的文件系统数据结构存储到磁盘上,这些数据结构包括空闲和已分配的空间以及一个初始为空的目录。

 

计算机启动时需要运行一个初始化程序(自举程序),它初始化 CPU、寄存器、设备控制器和内存等,接着启动操作系统。为此,自举程序应找到磁盘上的操作系统内核,装入内存,并转到起始地址,从而开始操作系统的运行。自举程序通常保存在 ROM 中,为了避免改变自举代码而需要改变 ROM 硬件的问题,故只在 ROM 中保留很小的自举装入程序,将完整功能的自举程序保存在磁盘的启动块上,启动块位于磁盘固定位。拥有启动分区的磁盘称为启动磁盘或系统磁盘。

 

以上内容均来自王道书籍及相关课程等

posted @ 2019-08-21 15:27  宁任翃  阅读(647)  评论(0编辑  收藏  举报