我们说过对于操作系统设计人员来说,我们关心的是文件是如何实现的。那么文件的实现意味着什么呢?或者文件的实现究竟是什么意思呢?
文件的实现,归根结底,就是要能够把文件的内容存放在合适的地方,并能够在需要时很容易地读出这些数据。这样,文件的实现要解决的就是如下几个问题:
给文件分配磁盘空间。
记住这些磁盘空间的位置。
将文件内容存放在这些空间。
给文件分配磁盘空间就是要按照用户要求或文件大小分配恰当容量的磁盘空间,
记录这些空间的位置对将来的文件访问至关重要;
将文件内容存放到这些空间中则可以通过磁盘本身的驱动器实现。
上述3点均需要了解数据在磁盘上的存放方式。
数据在磁盘上的存放方式,就像程序在内存中存放的方式那样,有下面两种:
连续空间存放方式
非连续空间存放方式
其中非连续空间存放又可以分为链表方式和索引方式。
连续空间存放方式
这是任何人均能想出来的办法。在一个文件需要磁盘空间时,为其分配一片连续的磁盘空间,这样一个文件的数据紧密相连,读写起来非常方便。在这种模式下,一个文件占住一片连续的数据块,这种连续的块通常叫做盘区(extent)。连续存放方式的读写效率很高
,因为一次磁盘寻道就可以读出整个文件。数据库文件就要求连续存放。所以装数据库的话最好在一个空的磁盘上装,如果你装在一个放了很多东西的磁盘上你就会发现系统运行很慢。
使用连续存放的方式必须知道一个文件所需要的空间大小。所以使用这种方式必须事先声明所需的最大空间是多少。文件系统则按照这个声明在磁盘上寻找一片足够大的自由空间并把它分配给该程序。而这种寻找自由空间的任务通常由一个适配算法来负责。图17-3描述的就是连续存放方式下文件A、B、C、D、E的一种可能分配方式。
由于文件的连续存放方式与程序在内存中的连续存放方式非常相似,因此其优缺点也非常相似。具体来说,文件的连续存放的优点就是简单:从文件名到文件地址的映射变为从文件名到文件第一个数据块的地址映射。即只要给出I-NODE地址和文件大小,就可以寻找到所有的文件数据块。这个和内存管理中的基址和极限很相似。另外一个优点是读写效率高。
文件连续存放的缺点自然也与内存的连续分配的缺点一样:空间浪费(磁盘碎片)和不易扩展。在图17-3中,如果文件D被删除,磁盘上就留下一块空缺。这时,如果新来的文件小于其中的一个空缺,我们就可以将其放在相应空缺里。但如果该文件的大小大于所有的空缺,但却小于空缺大小之和,则虽然磁盘上有足够的空缺,但该文件还是不能存放,如图17-4所示。
当然,我们可以通过将现有文件进行挪动来腾出空间以容纳新的文件。但在磁盘上挪动文件非常费时,恐怕令人无法忍受。
除了磁盘碎片(空间浪费)外,另一个缺点是文件扩展十分不便。例如,图17-3中的文件D想扩大一下,需要更多的磁盘空间,有什么办法吗?自然没有什么好办法。唯一的可能是将文件D放到磁盘上另一片空间更大的连续空间里;或者将与D相邻的文件挪开为D让出空间。不管哪种办法,效率都非常低。
那么有没有什么比较好的办法解决上述问题呢?有,就是改变文件的存放方式。因为这些文件均是因为文件块需要连续才造成的。因此,我们的解决办法就是非连续空间存放方式。
总结
- 连续存储简单,但是会造成空间浪费
- 连续存储扩展不方便