1、第二十八讲 文件管理之文件存储空间管理文件存储空间的管理,就是空闲空间的管理。下面介绍几个常用的管理方法:1 空闲表法和空闲链表法1.1 空闲表法空闲表:系统为空闲区建立一张空闲表,每个空闲区对应于一个空闲表项,其中包括表项序号、该空闲区的第一个盘块号、该区的空闲盘块数等信息。再将所有空闲区按其起始盘块号递增的次序排列,如下图。序号 第一空闲盘块号 空闲盘块数1 2 42 9 33 15 54 存储空间的分配和回收: 与内存的动态分配类似,同样是采用首次适应算法、循环首次适应算法等。 内存管理中虽然很少采用连续分配方式,然而在外存的管理中,由于它具有较高的分配速度,可减少访问磁盘的 I/O 频
2、率,故仍可采用连续分配算法。1.2 空闲链表法空闲链表法是将所有空闲盘区拉成一条空闲链。根据构成链所用基本元素的不同,可把链表分成两种形式:1. 空闲盘块链:将磁盘上的所有空闲空间,以盘块为单位拉成一条链。分配存储空间时,系统从链首开始,依次摘下适当数目的空闲盘块分配给用户。释放存储空间时,系统将回收的盘块依次插入空闲盘块链的末尾。优点:是用于分配和回收一个盘块的过程非常简单缺点:是分配盘块时,可能要重复操作多次2. 空闲盘区链:将磁盘上的所有空闲盘区(每个盘区可包含若干盘块)拉成一条链。 在每个盘区上除含有用于指示下一个空闲盘区的指针外,还应有能指明本盘区大小的信息。 分配盘区的方法与内存动
3、态分区分配类似,通常采用首次适应算法。 在回收盘区时,同样也要将回收区与相邻的空闲盘区相合并。 在采用首次适应算法时,为提高对空闲盘区的检索速度,可以采用显式链接方法,亦即,在内存中为空闲盘区建立一张链表。2 位示图法2.1 什么是位示图?位示图是利用二进制的一位来表示磁盘中一个盘块的使用情况。0 表示盘块空闲,1 表示已分配。磁盘上所有盘块所对应的位构成一个集合,称为位示图。通常可用 m*n 个位数来构成位示图,并使 m*n 等于磁盘的总块数。如下图。可看成是二维数组。2.2 盘块的分配根据位示图进行盘块分配时,可分三步进行:1) 顺序扫描位示图。找到 0 二进制位。2) 将所找到的一个或一
4、组二进制位,转换成与之对应的盘块号。盘块号=列数*(i-1)+j; ( i,j,b(盘块号)都从 1 开始)盘块号=列数*i+j+1; ( i,j 从 0 开始,b 从 1 开始)3) 修改位示图。令 mapI,j=1i,j,b(盘块号)都从 1 开始。2.3 盘块的回收盘块的回收分两步:1) 将回收盘块的盘块号转换成位示图中的行号和列号。转换公式为( i,j,b(盘块号)都从 1 开始):i=(盘块号-1) 列数+1j=(盘块号-1)mod 列数+1i,j 从 0 开始,b 从 1 开始:i=(盘块号-1) 列数j=(盘块号-1)mod 列数2) 修改位示图。令 mapI,j=0公式中减 1
5、 加 1 的目的是凑齐最后一列的得数!优点是从位示图中很容易找到一个或一组相邻接的空闲盘块。常用于微型机和小型机中。3 成组链接法3.1 引入空闲表法和空闲链表法都不适用于大型文件系统,因为这会使空闲表或空闲链表太长。在 UNIX 系统中采用的是成组链接法是将上述两种方法结合而形成的一种空闲盘块管理方法,它兼备了上述方法的优点而克服了表太长的缺点。3.2 空闲盘块的组织 空闲盘块号栈。用来存放当前可用的一组空闲盘块的盘块号(最多含 100 个号) ,以及栈中尚有的空闲盘块号数 N。引入一个数据结构,栈 N 还兼作栈顶指针。例如当 N=100 时,它指向 S.free(99)。S.free(0)
6、是栈底,栈满时栈顶为 S.free(99)。实际上就是利用 N1 来做下标。 文件中的所有空闲盘块,被分成若干个组,如有 100000 个盘块,每 100 块为 1 组,将会分成 1000 个组。 将每一组含有的盘块总数 N 和该组的盘块号,记入其前一组的第一个盘块的S.free(0)S.free(99)中。这样由各组的第一个盘块形成了一条链。 将第一组的盘块总数和所有的盘块号,记入空闲盘块号栈中,作为当前可供分配的空闲盘块号。 最末一组只有 99 个盘块,其盘块号分别记入其前一组的 S.free(1)S.free(99)中,而在 S.free(0)中则存放 0,作为空闲盘块链的结束标志。空闲
7、盘块的成组链接法示意图3.3 空闲盘块的分配 首先检查空闲盘块号栈是否上锁,如没有,便从栈顶取出一空闲盘块号,将与之对应的盘块分配给用户,然后将栈顶指针下移一格 若该盘块号已是栈底,即 S.free(0),这是当前栈中最后一个可供分配的盘块号。由于在该盘块号所对应的盘块中即有下一组可用的盘块号,因此须调用磁盘读过程,将该盘块内容读入栈中,作为盘块号栈的新内容,并把原栈底盘块分配出去。3.4 空闲盘块的回收 将回收盘块的盘块号记入空闲盘块号栈的顶部,并执行空闲盘块号加 1 操作。 当栈中空闲盘块号数目已达 100 时,表示栈已满,便将现有栈中的 100 个盘块号,记入新回收的盘块中,再将其盘块号作为新栈底。