文件对用户来说是连续的逻辑地址空间,它是存储在磁盘上的,文件是记录在外存上的具有名字的相关信息的集合,文件里面通常保存数据或程序。
文件的分类可以按照如下类别来分:
无论将文件如何来分类,文件都有一些共性的东西,我们称之为文件的属性,通常有如下属性:
上述的这些文件属性信息会保存在磁盘上的目录结构中。
用户和文件系统往往从不同的角度对待同一个文件的:
这样就导致了文件有两种形式的结构,即文件的逻辑结构和文件的物理结构:
物理结构直接影响存储空间的使用和检索文件信息的速度,逻辑文件保存到存储介质上的工作由文件系统来做,这样可减轻用户的负担。
文件从逻辑结构上分成二种形式,一种是无结构的流式文件,另一种是有结构的记录式文件:
我们重点讨论的是记录式的文件,记录文件有顺序、索引、索引顺序文件几种。
前面提到文件有多种存储结构,在访问文件时,所采用的方式也是和文件的组织方式密切相关,常用的存取方式有如下两种:
顺序存取是最简单的访问方式,它就是按照文件信息的逻辑顺序依次存取:
顺序存储示意图如下图所示,当前指针 (Current position) 可以向后读,也可以回到起始位置:
直接/随机存取可以直接定位到文件中的任何一个记录,而不需要像顺序存取一样要把路径中的所有记录过一遍。
对于连续文件(固定长度),第 i i i 个记录的地址( a d d r 0 addr_0 addr0 为首记录地址, L L L 为记录长度): r p t r = a d d r 0 + i ∗ L rptr=addr_0+i*L rptr=addr0+i∗L,在非定长文件中 L L L 的值不固定,所以非定长文件不支持随机存储。
对于索引文件,是支持随机存取的,因为我们可以先随机查找索引表,再取地址。
文件的访问方式不仅和文件的存储方式有关,还和文件的存储设备有关,因为文件时保存在存储设备上的,文件自身也带有物理设备的特性。
文件的存储设备主要有磁带,磁盘,光盘等,存储设备的特性可以决定文件的存取方法,对于上述的几种存储设备,它们都是以块为单位存储数据的,因此文件的存储设备常常划分为若干大小相等的物理块,以块为单位进行信息的存储、传输。
以磁带为例,磁带可以永久保存大容量数据,它是一种顺序存取设备,即前面的物理块被存取访问之后,才能存取后续物理块的内容。磁带存取速度较慢:主要用于后备存储,或存储不经常用的信息,或用于传递数据的介质,现在磁带已经基本上被淘汰了。下图是磁带存储示意图:
再以磁盘为例,磁盘是一种随机存储设备,它既可以顺序存取,也可以随机存取。它可以直接定位到某个磁道上的某个扇区,如下图所示:
用户按逻辑结构使用文件,文件的物理结构对用户来说是不必关心的,但对文件系统来说却是至关重要的,因为它直接影响存储空间的使用和检索文件信息的速度。文件系统按物理结构管理文件,当用户请求读写文件时,文件系统必须实现文件的逻辑结构与物理结构之间的转换。
文件的物理结构指的是文件在外存的存放组织形式,文件的物理结构与存储设备的特性有很大关系,前面提到过文件的存储设备通常划分为大小相等的物理块,物理块是分配及传输信息的基本单位,一个物理块中可以存放若干个逻辑记录,一个逻辑记录也可以存放在若干个物理块中。
所以文件的物理结构取决于外存的分配方式,当采用连续分配方式时,就是顺序结构;当采用链接分配方式时,就是链接结构;当采用索引分配方式时,就是索引结构。
这是最简单的物理文件结构,它将逻辑上连续的文件信息依次存放在外存连续的物理块中。如下图表示磁盘的存储空间,当文件要存储的时候,就为它找一段连续的存储空间存放,图中相同颜色的物理块表示一个文件,可以发现它们都是连续存放的。当我们需要找到某个文件的时候,要知道文件的首地址和长度,而这两个值都是保存在目录中的:
在这种分配方式下,每一个文件占用一个连续的磁盘块的集合,它的实现也非常简单,只需要起始块号和长度。同时它也可以随机存取,因为目录中保存了起始地址和长度,可以直接定位到某个文件。若是存储在磁盘中,其所需的磁盘寻道次数和寻道时间也比较少。
这种分配方式也有不足的地方,如现在有一个文件需要占据10个物理块,若查询内存剩余容量可以发现剩余有15个内存卡(以上图为例),但是依然无法分配,因为并没有10个连续的物理块,这个时候就出现了外碎片问题。
另外这种分配方式下文件不能动态增长,由于分配方式时顺序的,所以存储的方向也是固定的,如果某个文件要添加内容,可能导致物理块不够用,比如文件tr
想增加3个物理块,就无法完成。
顺序结构最大的问题就是外碎片问题,造成这个问题的主要原因就是顺序分配,参照内存中解决外碎片的方法,文件的物理结构也可以采用离散的分配方式,即采用链接结构。
在链接分配方式下按所需分配磁盘块,通过链接指针链接在一起,如下图只需要知道起始块和最后一块即可:
可以发现一个文件的物理块分散在磁盘的各个地方,在这种分配方式下消除了外碎片问题,但是缺点是无法支持随机存取了,若想知道文件的逻辑第三个物理块,则必须从首个物理块开始找到第三个块,而不能直接定位到第三个物理块。同时由于是指针链接,指针占据了一定的空间,而且存取速度较慢,物理块离散的分布,在磁盘存储中会带来更多的寻道次数和寻道时间。另外在这种分配方式下,只要磁盘中还有空间,文件时可以动态增长的。
解决指针占据空间的问题可以将多个块组成簇,以簇为单位分配,指针占用百分比减少,但增加内碎片,比如规定4个物理块为一个簇,每次分配都是4个物理块为单位分配。
为了支持随机存取,引入了文件分配表FAT (File allocation table ),每个磁盘会有一张文件分配表,里面的表项是和磁盘的物理块个数是一一对应的,每个表项存的内容就是该物理块的下一个物理块在什么地方,如下图所示,要找到某个文件只需要知道文件的起始地址就可以了,这样就间接的实现了随机存取,若要寻找文件逻辑上的第三个物理块,则只需要查询文件分配表即可,查找速度会非常快。:
回顾顺序结构和链接结构,顺序结构支持随机存取,但有外碎片;链接结构没有外碎片,但不能直接存取,虽然引入的FAT可以随机存取,但需要占用较大的内存空间。
事实上,打开某个文件时,只需知道该文件所在的盘块号, 一个文件的信息存放在若干不连续物理块中,系统为每个文件建立一个索引表,并将这些块的块号存放在索引表中,一个索引表就是磁盘块地址数组,其中第 i i i 个条目指向文件的第 i i i 块,如下图,所有灰色的物理块同属于一个文件jeep
,文件目录中会保存这个文件的索引表的编号,在索引表会找到该文件对应的所有物理块。这个索引表也是需要保存的,我们把它也保存在磁盘中,图中的物理块19
,叫做索引块:
可以发现索引分配是支持随机存取的,由于它也是一种离散的分配方式,所以它也没有外碎片。索引分配显然也是支持文件动态增长的。但是要建立索引表放在磁盘上,所以索引表是要占据磁盘空间的,同时因为是离散分配,也无法避免的增加了较多的寻道次数和寻道时间。
由于文件的大小是不定的,所以合理的设计索引表会提高检索速度,也能减少空间开销。当文件很小的时候,一张索引表就可以解决,当文件很大的时候,一张索引表可能就放不下了,因此有如下两种方案:
在两级索引分配方式,若每个盘块大小为
1KB
,每个盘块号占4字节
,则一个索引块中可存放256个盘块号
,则两级索引最多可包含的盘块号总数为64K
个(256*256)
。因此,所允许的文件的最大长度为64MB(64K*1KB)
。
有些系统保存了成百万的文件,为了管理这些数据,需要组织他们,所以引入了目录管理,文件目录通常分为两部分:
目录是一个包含着所有文件信息的节点的集合,每一个目录项对应着一个文件,如下图:
目录本身也是要保存下来的,目录和文件都是保存在磁盘上的,在目录中通常会保存文件的名称、类型、地址、当前长度、最大长度、最后访问时间、数据最后更新时间、所有者ID、保护信息等信息。
这些信息具体保存在文件控制块FCB中,用于描述和控制文件的数据结构,它至少要包括文件名和存放文件的盘物理地址。文件控制块的有序集合称为文件目录,即一个文件控制块FCB就是一个文件目录项。文件控制块FCB中保存的内容大致可以分为如下三类:
目录中就是所有文件控制块FCB的集合,对FCB的管理应该满足如下要求:
下图就是最简单的单级目录结构,所有文件对应这一个FCB表项,在单级目录结构中,要找到一个文件则要遍历FCB,而且由于是单级结构,不允许出现重命名,也不允许分组。:
为解决一级目录文件命名冲突,并提高对目录文件检索速度而改进,可以把目录分为两级:
这样在不同主文件目录下的不同文件可以重名,而且用户要查找文件只需要在自己的主目录下查找即可,如下图所示:
在二级目录结构下依然是无法分组的,为了解决这个问题引入了树型目录结构,如下图所示:
在树形目录结构下,层次结构清晰,便于管理和保护,有利于文件分类,解决重名问题,提高文件检索速度。但查找一个文件按路径名逐层检查,由于每个文件都放在外存,多次访盘影响速度。由于树形的叶子是不会重合的,所以不支持文件共享。
在有些系统中要求实现文件共享,这就引入了无环图结构目录,如下图所示,两个分支下的count
都指向了同一个文件:
在这种方式下,当某一方去修改这个文件时,如删除了这个文件,那么另一方指向这个文件的指针就是一个悬挂指针,解决方案有两种:
1
时,这个文件就是一个独享文件,当这个计数器为0
时,这个文件就真正的被删除了。在有的系统中要求文件可以指向目录,这就引入了普通图结构目录,如下图所示:
这种结构下就会出现环,当查找某个文件时就可能陷入某个环,保证无环的方式有如下几种: