- 在 ”L28 生磁盘的使用“ 中提到,磁盘在完成上一个读写任务后,就会从请求访问磁盘的进程请求队列中取出下一个要访问的盘块号,而这个盘块号,就是通过文件来得到的,这样,用户操作文件,就会发送盘块号给请求队列,再和 “L28 生磁盘的使用“ 的内容相结合,就实现了将文件储存在磁盘上。
L29 从生磁盘到文件
文件的引出
在 ”L28 生磁盘的使用“ 中提到,磁盘在完成上一个读写任务后,就会从请求访问磁盘的进程请求队列中取出下一个要访问的盘块号,而这个盘块号,就是通过文件来得到的,这样,用户操作文件,就会发送盘块号给请求队列,再和 “L28 生磁盘的使用“ 的内容相结合,就实现了将文件储存在磁盘上。
之所以引入文件,是因为对用户来说,如果让他用盘块号来访问磁盘,则他在使用之前需要知道扇区、盘块等知识,不太友好,所以操作系统在盘块概念的基础之上,又抽象出文件的概念,来方便用户使用磁盘。
★用户眼里的文件是字符序列(字符流),磁盘上的文件是盘块集合,所以文件就是字符流和盘块集合之间的映射关系。这一节的目的就是讲述如何从字符序列得到盘块号。
文件的映射作用
接下来以一个例子来帮助更好地理解文件的映射作用:
如下图所示的一个
test.c文件,在用户眼里就是一个字符序列,现在用户发现第 200-202 的字符有错误,要删除,于是用户进行删除操作,而第 200-202 字符对应磁盘中的盘块号是 789,于是操作系统就会将 789 这个盘块号插入请求访问磁盘的进程请求队列中,等待访问磁盘,当访问磁盘上对应盘块号为 789 的盘块后,就会删除里面的内容,然后再从用户的角度来看,第 200-202 的字符就被删除了。第 200-202 字符对应盘块号 789,就是文件的映射作用。
连续结构实现文件
我们可以用连续结构来实现文件(当然还有其他结构),如上图所示,假设一个盘块的大小是 100 个字符(操作系统初始化时设置的参数),为了知道
test.c文件的第 200-202 个字符存储在哪个盘块中,就需要知道test.c文件的起始盘块号,如上图所示,假设该文件的起始盘块号为 6,那么第 200-202个字符就应该存储在第 (200/100+6=)8 个盘块中。我们可以将文件的起始盘块号的信息存储在 TCB,即文件控制块中。连续结构适合文件直接读写磁盘,但不适用于文件动态变化。
链式结构实现文件
链式结构实现文件使用的是链表的方式,即在每个盘块中还应该存储下一个盘块的位置信息,如下图所示。
链式结构适用于文件的动态变化,但由于需要从第一个盘块起一步步找到所需的盘块,所以读写磁盘所需时间长。
★索引结构实现文件
索引结构实现文件是连续结构和链式结构的综合,在
test.c文件的 FCB 中存储有索引块的盘块号,在索引块中存储有对应各个逻辑盘块号的物理盘块号,例如下图中逻辑上第 2 个盘块的物理盘块号就是 17,根据索引结构,既可以对磁盘上的盘块进行直接的读写,也可以实现文件的动态变化。在一个实际系统中,使用的是多级索引结构,但归根结底,也就是索引结构。