1.文件控制块(实现文件目录的关键数据结构)
目录文件中的一条记录就是文件控制块(FCB)
FCB的有序集合称为“文件目录”,一个FCB就是一个文件目录项。
1.FCB的组成
- FCB中包含了文件的基本信息(文件名、物理地址、逻辑结构、物理结构等),
- 存取控制信息(是否可读/可写、禁止访问的用户名单等),
- 使用信息(如文件的建立时间、修改时间等)。
- 最重要,最基本的还是文件名、文件存放的物理地址。
FCB 实现了文件名和文件之间的映射。使用户(用户程序)可以实现“按名存取”。
2.需要对目录的操作
- 搜索:当用户要使用一个文件时,系统要根据文件名搜索目录,找到该文件对应的目录项
- 创建文件:创建一个新文件时,需要在其所属的目录中增加一个目录项
- 删除文件:当删除一个文件时,需要在目录中删除相应的目录项
- 显示目录:用户可以请求显示目录的内容,如显示该目录中的所有文件及相应属性
- 修改目录:某些文件属性保存在目录中,因此这些属性变化时需要修改相应的目录项(如:文件重命名)
2.目录结构
1.单级目录结构
早期操作系统并不支持多级目录,整个系统中只建立一张目录表,每个文件占一个目录项。
单级目录实现了“按名存取”,但是不允许文件重名。
在创建一个文件时,需要先检查目录表中有没有重名文件,确定不重名后才能允许建立文件,并将新文件对应的目录项插入目录表中。
显然,单级目录结构不适用于多用户操作系统。
2.两级目录结构
早期的多用户操作系统,采用两级目录结构。
分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User Flie Directory)
允许不同用户的文件重名。文件名虽然相同,但是对应的其实是不同的文件。
两级目录结构允许不同用户的文件重名,也可以在目录上实现实现访问限制(检查此时登录的用户名是否匹配)。
但是两级目录结构依然缺乏灵活性,用户不能对自己的文件进行分类。
3.多级目录结构(树形目录结构)
1.绝对路径
用户(或用户进程)要访问某个文件时要用文件路径名标识文件,文件路径名是个字符串。
各级目录之间用“/”隔开。
从根目录出发的路径称为绝对路径。
2.相对路径
很多时候,用户会连续访问同一目录内的多个文件(比如:接连查看"2015-08"日录内的多个照片文件),
每次都从根目录开始查找,是很低效的。
因此可以设置一个“当前目录”。
例如,此时已经打开了“照片”的目录文件,也就是说,这张目录表已调入内存,那么可以把它设置为“当前目录”。
当用户想要访问某个文件时,可以使用从当前目录出发的“相对路径”。
在 Linux 中,“.”表示当前目录,因此如果“照片”是当前目录,则"自拍.jpg"的相对路径为:“./2015-08/自拍.jpg”。
4.无环图目录结构
树形目录结构可以很方便地对文件进行分类,层次结构清晰,也能够更有效地进行文件的管理和保护。
但是,树形结构不便于实现文件的共享。为此,提出了“无环图目录结构”。
可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。
1.共享计数器
需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。
用户提出删除结点的请求时,只是删除该用户的FCB、并使共享计数器减1,并不会直接删除共享结点。
注意:
共享文件不同于复制文件。
在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化。
3.索引结点(对文件控制块(FCB)的优化)
1.索引结点
- 当找到文件名对应的目录项时,才需要将索引结点调入内存,索引结点中记录了文件的各种信息,包括文件在外存中的存放位置,根据“存放位置”即可找到文件。
- 存放在外存中的索引结点称为“磁盘索引结点”,当索引结点放入内存后称为“内存索引结点”。
- 相比之下内存索引结点中需要增加一些信息,比如:文件是否被修改、此时有几个进程正在访问该文件等。
2.优化效率对比
- 假设一个FCB是64B,磁盘块的大小为1KB,则每个盘块中只能存放16个FCB。若一个文件目录中共有640个目录项,则共需要占用640/16=40个盘块。因此按照某文件名检索该目录,平均需要查询320个目录项,平均需要启动磁盘20次(每次磁盘I/O读入一块)。
- 若使用索引结点机制,文件名占14B,索引结点指针站2B,则每个盘块可存放64个目录项,那么按文件名检索目录平均只需要读入320/64=5个磁盘块。显然,这将大大提升文件检索速度。