文件的管理
目录
一、文件的定义
二、文件的属性
三、文件的逻辑结构[文件内部的数据应该怎样组织起来?]
1.无结构文件
2.有结构文件
(1)顺序文件
(2)索引文件
(3)索引顺序文件
四、目录结构[文件之间应该怎样组织起来?]
1.文件目录的实现
2.文件控制块[实现文件目录的关键数据结构]
3.目录结构
(1)单级目录结构
(2)两级目录结构
(3)多级目录结构[树形]
(4)无环图目录结构
4.索引结点[对文件控制块的优化]
五、文件的操作[操作系统应该向上提供哪些功能?]
六、文件的物理结构[文件应如何存放在外存中?]
1.磁盘块
2.连续分配
(1)支持随机访问
(2)顺序读写速度最快
(3)拓展不方便
(4)会产生磁盘碎片
(5)总结:
3.链接分配
(1)隐式链接
①地址转换:
②方便拓展
③总结
(2)显式链接
①逻辑地址转变
②总结
4.索引分配
(1)逻辑地址转换
(2)索引块大小不够的解决方案
①链接方案
②多层索引
③混合索引
④总结
5.总结
七、存储空间的管理
1.文件的划分与初始化
(1)文件卷(逻辑卷)的概念
(2)目录区与文件区
2.管理方式
(1)空闲表法
分配
回收
(2)空闲链表法
①空闲盘块链
②空闲盘区链
(3)位示图法
(4)成组链接法
分配
回收
八、文件共享
1.硬链接[基于索引结点]
2.软连接[基于符号链]
九、文件保护
1.口令保护
2.密码保护
3.访问控制
十、文件系统的层次结构
十一、文件系统的全局结构
1.新磁盘
2.物理格式化
3.逻辑格式化
4.文件系统在内存中的结构
十二、虚拟文件系统
1.虚拟文件系统的特点
2.文件挂载系统
一、文件的定义
一组有意义的信息的集合。
二、文件的属性
文件名 | 由创建文件的用户决定文件名,主要是为了方便用户找到文件,同一目录下不允许有重名文件。 |
标识符 | 一个系统内的各文件标识符唯一,对用户来说毫无可读性,因此标识符只是操作系统用于区分各个文件的一种内部名称。 |
类型 | 指明文件的类型 |
位置 | 文件存放的路径(让用户使用); |
在外存中的地址(操作系统使用,对用户不可见) | |
大小 | 指明文件大小 |
创建时间 | |
上次修改时间 | |
文件所有者信息 | |
保护信息 | 对文件进行保护的访问控制信息 |
三、文件的逻辑结构[文件内部的数据应该怎样组织起来?]
所谓的“逻辑结构”,就是指在用户看来,文件内部的数据应该是如何组织起来的。
文件 | 无结构文件 | 一系列二进制字符流组成 | |
有结构文件 | 记录 | 数据项 |
1.无结构文件
文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。如:Windows操作系统中的.txt 文件。
2.有结构文件
由一组相似的记录组成,又称“记录式文件”。每条记录又若干个数据项组成。如:数据库表文件。一般来说,每条记录有一个数据项可作为关键字。根据各条记录的长度(占用的存储空间)是否相等,又可分为定长记录和可变长记录两种。
例如:
这个有结构文件由可变长记录组成,由于各个学生的特长存在很大区别,因此“特长”这个数据项的长度不确定,这就导致了各条记录的长度也不确定。当然,没有特长的学生甚至可以去掉“特长”数据项。
根据结构文件中的记录在逻辑结构上是如何组织的,又可以分为三类:
顺序文件 | |
索引文件 | |
索引顺序文件 |
(1)顺序文件
文件的记录在逻辑上一个接一个的顺序排列,记录是定长的也可能是可变长的。各个记录在实际的物理存储上可以分为顺序存储和链式存储。
顺序存储 | 逻辑上相邻的记录,物理上也相邻。好比与顺序表。 | |
链式存储 | 逻辑上相邻的记录在物理上不一定相邻。好比与链表。 |
根据记录之间的顺序是否与关键字有关可分为:
串结构 | 记录之间的顺序与关键字无关[通常按照记录存入的时间决定记录的顺序] |
顺序结构 | 记录之间的顺序按关键字顺序排列 |
总结:
顺序文件 | 链式存储 | 无论是定长/可变长记录,都无法实现随机存取,每次只能从第一个记录开始依次往后查找 | ||
顺序存储 | 可变长记录 | 无法实现随机存取。每次只能从第一个记录开始依次往后查找 | ||
定长记录:可实现随机存取。 | 采用串结构 | 无法快速找到某关键字对应的记录 | ||
采用顺序结构 | 可以快速找到某关键字对应的记录 (如折半查找) |
可见,顺序文件的缺点是增加/删除一个记录比较困难(如果是串结构则相对简单)。
(2)索引文件
又想变长记录,还想实现快速查找。
索引表本身是定长记录的顺序文件。因此可以快速找到第i个记录对应的索引项。
可将关键字作为索引号内容,若按关键字顺序排列,则还可以支持按照关键字折半查找。每当要增加/删除一个记录时,需要对索引表进行修改。由于索引文件有很快的检索速度,因此主要用于对信息处理的及时性要求比较高的场合。
另外,可以用不同的数据项建立多个索引表。如:学生信息表中,可用关键字“学号”建立一张索引表。也可用“姓名”建立一张索引表。这样就可以根据“姓名”快速地检索文件了。上(Eg:SQL就支持根据某个数据项建立索引的功能)
(3)索引顺序文件
索引文件的缺点:每个记录对应一个索引表项,因此索引表可能会很大
比如:文件的每个记录平均只占8B,而每个索引表项占32个字节,那么索引表都要比文件内容本身大4倍,这样对存储空间的利用率就太低了。
索引顺序文件是索引文件和顺序文件思想的结合。索引顺序文件中,同样会为文件建立一张索引表,但不同的是:并不是每个记录对应一个索引表项,而是一组记录对应一个索引表项。
用这种策略确实可以让索引表“瘦身”。
若一个顺序文件有10000个记录,则根据关键字检索文件,只能从头开始顺序查找(这里指的并不是定长记录、顺序结构的顺序文件),平均须查找5000个记录。若采用索引顺序文件结构,可把10000个记录分为√10000=100组,每组100个记录。则需要先顺序查找索引表找到分组(共100个分组,因此索引表长度为100,平均需要查50次),找到分组后,再在分组中顺序查找记录(每个分组100个记录,因此平均需要查50次)。可见,采用索引顺序文件结构后,平均查找次数减少为 50+50 =100 次。
同理,若文件共有 106个记录,则可分为1000个分组,每个分组1000个记录。根据关键字检索一个记录平均需要查找 500+500=1000次。这个查找次数依然很多,如何解决呢?
建立多级索引结构:
为了进一步提高检索效率,可以为顺序文件建立多级索引表。例如,对于一个含 10^6个记录的文件,可先为该文件建立一张低级索引表,每100个记录为一组,故低级索引表中共有10000个表项(即10000个定长记录),再把这 10000个定长记录分组,每组100个,为其建立顶级索引表,故顶级索引表中共有100个表项。
四、目录结构[文件之间应该怎样组织起来?]
1.文件目录的实现
文件与FCB一一对应,FCB的有序集合称为文件目录,一个FCB就是一个文件目录项。
且:目录本身就是一种有结构文件,由一条条记录组成。每条记录对应一个在该放在该目录下的文件。
2.文件控制块[实现文件目录的关键数据结构]
FCB中记录的内容:
文件名 | |
类型 | |
文件权限 | |
文件大小 | |
文件在外存中的物理地址 |
FCB中最重要的属性是文件名和文件在外存中的物理地址
FCB 实现了文件名和文件之间的映射。是用户(用户程序)可以实现“按名存取”的关键。
需要对目录进行哪些操作?
搜索: | 当用户要使用一个文件时,系统要根据文件名搜索目录,找到该文件对应的目录项 |
创建文件: | 创建一个新文件时,需要在其所属的目录中增加一个目录项 |
删除文件: | 当删除一个文件时,需要在目录中删除相应的目录项 |
显示目录: | 用户可以请求显示目录的内容,如显示该目录中的所有文件及相应属性 |
修改目录: | 某些文件属性保存在目录中,因此这些属性变化时需要修改相应的目录项(如:文件重命名) |
3.目录结构
(1)单级目录结构
早期操作系统并不支持多级目录,整个系统中只建立一张目录表,每个文件占一个目录项。
单级目录实现了“按名存取”,但是不允许文件重名;
在创建一个文件时,需要先检查目录表中有没有重名文件,确定不重名后才能允许建立文件,并将新文件对应的目录项插入目录表中。
显然,单级目录结构不适用于多用户操作系统。
(2)两级目录结构
早期的多用户操作系统,采用两级目录结构。分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User File Directory)。
主文件目录 | 记录用户名及相应用户文件目录的存放位置 |
用户文件目录 | 由该用户的文件FCB组成 |
允许不同用户的文件重名。文件名虽然相同,但是对应的其实是不同的文件
两级目录结构允许不同用户的文件重名,也可以在目录上实现访问限制(检查此时登录的用户名是否匹配)。但是两级目录结构依然缺乏灵活性,用户不能对自己的文件进行分类
(3)多级目录结构[树形]
从根目录出发 | 绝对路径 | 系统根据绝对路径一层一层地找到下一级目录。 | |
从当前目录出发 | 相对路径 | 很多时候,用户会连续访问同一目录内的多个文件。显然,每次都从根目录开始查找,是很低效的。因此可以设置一个“当前目录” |
用户(或用户进程)要访问某个文件时要用文件路径名标识文件,文件路径名是个字符串。各级目录之间用“/”隔开。
在Linux中,“.”表示当前目录;
可见,引入“当前目录”和“相对路径”后,磁盘/0的次数减少了。这就提升了访问文件的效率。
(4)无环图目录结构
树形目录结构可以很方便地对文件进行分类,层次结构清晰,也能够更有效地进行文件的管理和保护。但是,树形结构不便于实现文件的共享。为此,提出了“无环图目录结构”:
可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。
需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时,只是删除该用户的FCB、并使共享计数器减1,并不会直接删除共享结点。只有共享计数器减为0时,才删除结点。
注意:共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化。
4.索引结点[对文件控制块的优化]
其实在查找各级目录的过程中只需要用到“文件名”这个信息,只有文件名匹配时,才需要读出文件的其他信息。因此可以考虑让目录表“瘦身”来提升效率:
除了文件名之外的所有信息都放到索引结点中,每个文件对应一个索引结点
目录项中只包含文件名、索引结点指针,因此每个目录项的长度大幅减小
由于目录项长度减小,因此每个磁盘块可以存放更多个目录项,因此检索文件时磁盘I/0的次数就少了很多
此外:
磁盘索引结点 | 存放在外存中的索引结点称为“磁盘索引结点” | |
内存索引结点 | 当索引结点放入内存后称为“内存索引结点” | 相比之下内存索引结点中需要增加一些信息,比如:文件是否被修改、此时有几个进程正在访问该文件等。 |
五、文件的操作[操作系统应该向上提供哪些功能?]
操作 | 系统调用 | 传递参数 | 步骤 |
创建文件(create系统调用) | 可以“创建文件”(点击新建后,图形化交互进程在背后调用了“create 系统调用”) | 1.所需的外存空间大小 2.文件存放路径 3.文件名 | 1.在外存中找到文件所需的空间 2.创建该文件对应的目录项 |
删除文件(delete系统调用) | 可以“删除文件”(点了“删除”之后!图形化交互进程通过操作系统提供的删除文件”功能,即 delete 系统调用将文件数据从外存中删除) | 1.文件存放路径 2.文件名 | 1.找到文件名对应的目录项 2.回收文件占用的磁盘块 3.删除文件对应的目录项 |
读文件(read系统调用) | 可以“读文件”,将文件数据读入内存,才能让CPU处理(双击后,“记事本”应用程序通过操作系统提供的“读文件”功能,即read 系统调用,将文件数据从外存读入内存,并显示在屏幕上) | 进程使用 read系统调用完成写操作。需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要读入多少数据(如:读入1KB)、指明读入的数据要放在内存中的什么位置。操作系统在处理 read 系统调用时,会从读指针指向的外存中,将用户指定大小的数据读入用户指定的内存区域中。 | |
写文件(write系统调用) | 可以“写文件”,将更改过的文件数据写回外存(我们在“记事本”应用程序中编辑文件内容,点击“保存”后,“记事本”应用程序通过操作系统提供的“写文件”功能,即 write 系统调用:将文件数据从内存写回外存) | 进程使用 write 系统调用完成写操作,需要指明是哪个文件(在支持“打开文件”操作的系统中,只需要提供文件在打开文件表中的索引号即可),还需要指明要写出多少数据(如:写出1KB)、写回外存的数据放在内存中的什么位置操作系统在处理 write系统调用时,会从用户指定的内存区域中,将指定大小的数据写回写指针指向的外存。 | |
打开文件(open系统调用) | 读写之前要打开文件 | 1.文件存放路径 2.文件名 3.要对文件的操作类型 | 1.找到文件名对应的目录项 2.将目录项复制到内存中的“打开文件表”中。之后用户使用打开文件表的编号来指明要操作的文件。 |
关闭文件(close系统调用) | 读写之后要关闭文件 | 1.将进程的打开文件表相应表项删除 2.回收分配给该文件的内存空间等资源 3.系统打开文件表的打开计数器count减1,若count=0,则删除对应表项。 |
六、文件的物理结构[文件应如何存放在外存中?]
而“物理结构”指的是在操作系统看来,文件的数据是如何存放在外存中的。
1.磁盘块
与内存一样,外存也是由一个个存储单元组成的,每个存储单元可以存储一定量的数据(如 1B)。每个存储单元对应一个物理地址
操作系统以“块”为单位为文件分配存储空间,因此即使一个文件大小只有10B,但它依然需要占用 1KB 的磁盘块。外存中的数据读入内存时同样以块为单位
类似于内存分为一个个“内存块”,外存会分为一个个“块/磁盘块/物理。每个磁盘块的大小是相等的,每块一般包含2的整数幂个地址(如块”本例中,一块包含 2^10 个地址,即 1KB)。同样类似的是,文件的逻辑地址也可以分为(逻辑块号,块内地址),操作系统同样需要将逻辑地址转换为外存的物理地址(物理块号,块内地址)的形式。块内地址的位数取决于磁盘块的大小。
类似于内存分页,磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中,磁盘块的大小与内存块、页面的大小相同。
在内存管理中,进程的逻辑地址空间被分为一个一个页面同样的,在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空间也被分为了一个一个的文件“块”于是文件的逻辑地址也可以表示为(逻辑块号,块内地址)的形式,
2.连续分配
(1)支持随机访问
用户给出要访问的逻辑块号,操作系统找到该文件对应的目录项(FCB)
物理块号=起始块号+逻辑块号
当然,还需要检查用户提供的逻辑块号是否合法(逻辑块号>长度就不合法)
文件目录中记录存放的起始块号和长度(总共占用几个块。
可以直接算出逻辑块号对应的物理块号,因此连续分配支持顺序访问和直接访问(即随机访问)
(2)顺序读写速度最快
(3)拓展不方便
(4)会产生磁盘碎片
(5)总结:
思想 | 连续分配方式要求每个文件在磁盘上占有一组连续的块 |
优点 | ①支持顺序访问和随机访问(直接访问) |
②连续分配的文件在顺序读/写时速度最快 | |
缺点 | ①物理上采用连续分配的文件不方便拓展。 |
②物理上采用连续分配,存储空间利用率低,会产生难以利用的磁盘碎片可以用紧凑来处理碎片,但是需要耗费很大的时间代价 |
3.链接分配
链接分配采取离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种。
(1)隐式链接
①地址转换:
目录中记录了文件存放的起始块号和结束块号。当然,也可以增加一个字段来表示文件的长度
除了文件的最后一个磁盘块之外,每个磁盘块中都会保存指向下一个盘块的指针,这些指针对用户是透明的
用户给出要访问的逻辑块号i,操作系统找到该文件对应的目录项(FCB)
从目录项中找到起始块号(即0号块),将0号逻辑块读入内存,由此知道1号逻辑块存放的物理块号,于是读入1号逻辑块,再找到2号逻辑块的存放位置…………以此类推。
因此,读入i号逻辑块,总共需要i+1次磁盘I/O.
结论:采用链式分配(隐式链接)方式的文件,只支持顺序访问,不支持随机访问,查找效率低。另外,指向下一个盘块的指针也需要耗费少量的存储空间。
②方便拓展
若此时要拓展文件,则可以随便找一个空闲磁盘块,挂到文件的磁盘块链尾,并修改文件的FCB;
结论:采用隐式链接的链接分配方式,很方便文件拓展另外,所有的空闲磁盘块都可以被利用,不会有碎片问题外存利用率高。
③总结
思想 | 优点 | 缺点 |
除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针。文件目录包括文件第一块的指针和最后一块的指针。 | 很方便文件拓展,不会有碎片问题,外存利用率高。 | 只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量的存储空间。 |
(2)显式链接
把每个文件的各个盘块的链接信息显式的存在一章表中[FAT表,File Allocation Table(文件分配表)]:
文件目录中只需记录该文件的起始盘块。
注意:一个磁盘仅设置一张FAT开机时,将FAT读入内存,并常驻内存。FAT的各个表项在物理上连续存储,且每一个表项长度相同,因此“物理块号”字段可以是隐含的。
①逻辑地址转变
用户给出要访问的逻辑块号i,操作系统找到该文件对应的目录项(FCB).
从目录项中找到起始块号,若i>0,则查询内存中的文件分配表FAT往后找到i号逻辑块对应的物理块号。逻辑块号转换成物理块号的过程不需要读磁盘操作。
结论:采用链式分配(显式链接)方式的文件,支持顺序访问,也支持随机访问(想访问i号逻辑块时,并不需要依次访问之前的0~i-1号逻辑块),由于块号转换的过程不需要访问磁盘,因此相比于隐式链接来说,访问速度快很多。
显然,显式链接也不会产生外部碎片,也可以很方便地对文件进行拓展。
②总结
思想 | 优点 | 缺点 |
把用于链接文件各物理块的指针显式地存放在一张表中,即 文件分配表(FAT,FileAllocation Table)。一个磁盘只会建立一张文件分配表。开机时文件分配表放入内存,并常驻内存。 | 很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接来说,地址转换时不需要访问磁盘,因此文件的访问效率更高。 | 文件分配表的需要占用一定的存储空间。 |
4.索引分配
索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块(索引表的功能类似于内存管理中的页表--建立逻辑页面到物理页之间的映射关系)。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。
注:在显式链接的链式分配方式中,文件分配表FAT(常驻内存) 是一个磁盘对应一张。而索引分配方式中,索引表(在磁盘中)是一个文件对应一张。
(1)逻辑地址转换
用户给出要访问的逻辑块号i,操作系统找到该文件对应的目录项(FCB)
从目录项中可知索引表存放位置,将索引表从外存读入内存,并查找索引表即可只i号逻辑块在外存中的存放位置。
可见,索引分配方式可以支持随机访问文件拓展也很容易实现(只需要给文件分配一个空闲块,并增加一个索引表项即可)但是索引表需要占用一定的存储空间。
(2)索引块大小不够的解决方案
假设现在要存储一个文件,一个磁盘块的大小为1KB,一索引表项占4B,也即一个磁盘块可以存放256个索引表项,但是现在文件的大小超过了256个磁盘块怎么办?
①链接方案
如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。
假设磁盘块大小为1KB,一个索引表项占4B,则一个磁盘块只能存放256个索引项。若一个文件大小为 256*256KB=65.536KB=64MB该文件共有256*256个块,也就对应256*256个索引项,也就需要256个索引块来存储,这些索引块用链接方案连起来。若想要访问文件的最后一个逻辑块,就必须找到最后一个索引块(第256个索引块),而各个索引块之间是用指针链接起来的,因此必须先顺序地读入前255 个索引块。
②多层索引
建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。
假设磁盘块大小为1KB,一个索引表项占4B,则一个磁盘块只能存放256个索引项。
若某文件采用两层索引,则该文件的最大长度可以到256*256*1KB=65,536KB=64MB可根据逻辑块号算出应该查找索引表中的哪个表项。
如:要访问1026号逻辑块,则1026/256=4,1026%256=2因此可以先将一级索引表调入内存,查询4号表项将其对应的二级索引表调入内存,再查询二级索引表的2号表项即可知道1026号逻辑块存放的磁盘块号了访问目标数据块,需要3次磁盘I/0.
若采用三层索引,则文件的最大长度为256*256*256*1KB=16GB
采用K层索引结构,且顶级索引表未调)内存,则访问一个数据块只需要K+1次读磁盘操作
③混合索引
多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。
根据顶级索引表,计算该结构的最大文件长度:
8+256+65536=65800KB.
读盘次数:
若顶级索引表还没读入内存
访问0~7号逻辑块:两次读磁盘
访问8~263:三次读磁盘
访问264~65799:四次读磁盘
结论:对于小文件,只需较少的读磁盘次数就可以访问目标数据块:(一般计算机中小文件更多)
④总结
索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块(索引表的功能类似于内存管理中的页表--建立逻辑页面到物理页之间的映射关系)。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。若文件太大,索引表项太多,可以采取以下三种方法解决:
方案 | 链接索引 | 多层索引 | 混合索引 |
思想 | 如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。 | 建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。采用K层索引结构,且顶级索引表未调入内存,则访问-个数据块只需要K+1次读磁盘操作。 | 多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。 |
优点 | 对于小文件来说,访问一个数据块所需的读磁盘次数更少。 | ||
缺点 | 若文件很大,索引表很长,就需要将很多个索引块链接起来。想要找到i号索引块,必须先依次读入 0~i-1号索引块,这就导致磁盘I/0次数过多,查找效率低下。 | 即使是小文件,访问一个数据块依然需要K+1次读磁盘。 |
重要考点:
①要会根据多层索引、混合索引的结构计算出文件的最大长度(Key:各级索引表最大不能超过一个块);
②要能自己分析访问某个数据块所需要的读磁盘次数(Key: FCB中会存有指向顶级索引块的指针,因此可以根据FCB读入顶级索引块。每次读入下一级的索引块都需要一次读磁盘操作。另外,要注意题目条件--顶级索引块是否已调入内存)
5.总结
思想 | 目录项内容 | 优点 | 缺点 | ||
顺序分配 | 为文件分配的必须是连续的磁盘块 | 起始块号、文件长度 | 顺序存取速度快,支持随机访问 | 会产生碎片,不利于文件拓展 | |
链接分配 | 隐式[题目不说明就是隐式链接] | 除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针 | 起始块号、文件长度 | 可解决碎片问题,外存利用率高,文件拓展实现方便 | 只能顺序访问,不能随机访间。 |
显示 | 建立一张文件分配表(FAT),显式记录盘块的先后关系(开机后FAT常驻内存) | 起始块号 | 除了拥有隐式链接的优点之外,还可通过询内存中的FAT实现随机访间 | FAT需要占用一定的存储空间 | |
索引分配 | 为文件数据块建立索引表。若文件太大,可采用链接方案、多层索引、混合索引 | 链接方案记录的是第一个索引块的块号,多层/混合索引记录的是顶级索引块的块号 | 支持随机访问,易于实现文件的拓展 | 索引表需占用一定的存储空间。访问数据块前需要先读入索引块。若采用链接方案,查找索引块时可能需要很多次读磁盘操作, |
七、存储空间的管理
1.文件的划分与初始化
(1)文件卷(逻辑卷)的概念
存储空间的划分:将物理磁盘划分为一个个文件卷(逻辑卷、逻辑盘)
有的系统支持超大型文件,可支持由多个物理磁盘组成一个文件卷:
(2)目录区与文件区
目录区 | 文件区 |
目录区主要存放文件目录信息(FCB)、用于磁盘存储空间管理的信息 | 文件区用于存放文件数据 |
2.管理方式
(1)空闲表法
分配
与内存管理中的动态分区分配很类似,为一个文件分配连续的存储空间。同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。
回收
与内存管理中的动态分区分配很类似,当回收某个存储区时需要有四种情况。总之,回收时需要注意表项的合并问题。
①回收区的前后都没有相邻空闲区 | 空闲盘块表表项加一 |
②回收区的前后都是空闲区 | 合并,空闲盘块表表项减一 |
③回收区前面是空闲区 | 合并 |
④回收区后面是空闲区 | 合并 |
(2)空闲链表法
①空闲盘块链
以盘块为单位组成一条空闲链,空闲盘块中存着下一个空闲盘块的指针。
操作系统保存着链头、链尾指针
如何分配: | 如何回收: | 特点 |
若某文件申请K个盘块,则从链头开始依次摘下K个盘块分配,并修改空闲链的链头指针。 | 回收的盘块依次挂到链尾,并修改空闲链的链尾指针。 | 适用于离散分配的物理结构。为文件分配多个盘块时可能要重复多次操作 |
②空闲盘区链
以盘块为单位组成一条空闲链,连续的空闲盘块组成一个空闲盘区,空闲盘区的第一个空闲盘块记录了该空闲盘区的长度以及下一个空闲盘区的指针。
操作系统保存着链头、链尾指针
如何分配: | 如何回收: | 特点 |
若某文件申请K个盘块,则可以采用首次适应、最佳适应等算法,从链头开始检索按照算法规则找到一个大小符合要求的空闲盘区分配给文件。若没有合适的连续空闲块,也可以将不同盘区的盘块同时分配给一个文件,注意分配后可能要修改相应的链指针、盘区大小等数据 | 若回收区和某个空闲盘区相邻,则需要将回收区合并到空闲盘区中。若回收区没有和任何空闲区相邻,将回收区作为单独的一个空闲盘区挂到链尾。 | 离散分配、连续分配都适用。为个文件分配多个盘块时效率更高 |
(3)位示图法
每个二进制位对应一个盘块。在本例中,“0”代表盘块空闲“1”代表盘块已分配。
位示图一般用连续的“字”来表示,如本例中个字的字长是16位,字中的每一位对应一个盘块。因此可以用(字号,位号)对应一个盘块号。当然有的题目中也描述为(行号,列号)
注意题目条件:盘块号、字号、位号到底是从0开始还是从1开始
如本例中盘块号、字号、位号从0开始,若n表示字长
(字号,位号)=(i,j)的二进制位对应的:
盘块号=ni+j
字号=盘块号/n,位号=盘块号%n
如何分配: | 如何回收: |
若文件需要K个块, ①顺序扫描位示图,找到K个相或不相邻的“0”; | ①根据回收的盘块号计算出对应的字号、位号; |
②根据字号、位号算出对应的盘块号,将相应盘块分配给文件: | ②将相应二进制位设为“0” |
③将相应位设置为“1” |
(4)成组链接法
空闲表法和空闲链表法由于空闲表和空闲链表过大所以不适合大型文件系统,UNIX使用了成组链接法对磁盘块进行管理。
文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。
注1:若已经没有下组空闲快,此处设为某特殊值(例如-1)
注2:一个分组中的块号不需要连续,此处只是为了更方便看出各个分组的数量
分配
- 系统启动时,会将所有空闲盘块分成若干组。通常,每组含有一定数量的空闲盘块,比如每组有 100 个盘块。第一组的盘块总数及所有的盘块号会记录在超级块中,超级块位于内存中。
- 当需要分配一个空闲盘块时,首先检查超级块中第一组的盘块信息。
- 如果第一组中有空闲盘块,从第一组中取出一个盘块分配给请求者。同时,需要更新超级块中第一组的盘块信息,将第一组的盘块总数减一,并调整第一组的盘块号列表,去除刚刚分配出去的盘块号。
- 如果第一组的盘块被分配完了,那么将超级块中的第一组的盘块总数及盘块号信息保存下来,然后将下一组的盘块总数及盘块号信息读到超级块中,使其成为新的第一组,继续进行分配操作。
回收
- 当一个盘块被回收时,首先检查超级块中的第一组是否已满。
- 如果第一组未满,将回收的盘块号加入到第一组的盘块号列表中,并将第一组的盘块总数加一。
- 如果第一组已满,此时需要将第一组的盘块总数及盘块号信息保存到刚刚回收的那个盘块中。然后,将超级块中的第一组信息更新为刚刚回收的这个盘块的盘块号,以及总数为 1。接着,将回收的盘块号加入到新的第一组中,并将第一组的盘块总数更新为 2。
通过成组链接法,可以有效地管理空闲盘块,提高操作系统对磁盘空间的分配和回收效率。
八、文件共享
共享 | 复制 |
多个用户共享同一个文件,意味着系统中只有“一份”文件数据。并且只要某个用户修改了该文件的数据,其他用户也可以看到文件数据的变化。 | 如果是多个用户都“复制”了同一个文件,那么系统中会有“好几份”文件数据。其中一个用户修改了自己的那份文件数据,对其他用户的文件数据并没有影响。 |
1.硬链接[基于索引结点]
不同用户的文件目录项指向同一个索引结点。
索引结点里设置了个链接技术变量count,用于表示本索引结点上的用户目录项数。
多一个用户共享,count+1;
一个用户删除该文件,count-1,该用户目录项删除。
若count>0,说明还有别的用户要使用该文件,暂时不能把文件数据删除,否则会导致指针悬空
当count=0时系统负责删除文件。
2.软连接[基于符号链]
在一个 Link 型的文件中记录共享文件的存放路径(类似Windows 快捷方式)
操作系统根据路径一层层查找目录,最终找到共享文件
即使软链接指向的共享文件已被删除,Link型文件依然存在,只是通过 Link 型文件中的路径去查找共享文件会失败(找不到对应目录项)
由于用软链接的方式访问共享文件时要查询多级目录,会有多次磁盘I/0因此用软链接访问速度比硬链接的慢。
九、文件保护
1.口令保护
实现 | 优点: | 缺点: |
为文件设置一个“口令”(如:abc112233),用户请求访问该文件时必须提供“口令 口令一般存放在文件对应的 FCB 或索引结点中。用户访问文件前需要先输入“口令”,操作系统会将用户提供的口令与FCB中存储的口令进行对比,如果正确,则允许该用户访问文件 | 保存口令的空间开销不多,验证口令的时间开销也很小。 | 正确的“口令”存放在系统内部,不够安全。 |
2.密码保护
实现 | 优点: | 缺点: |
使用某个“密码”对文件进行加密,在访问文件时需要提供正确的“密码”才能对文件进行正确的解密 | 保密性强,不需要在系统中存储“密码” | 编码/译码,或者说加密/解密要花费一定时间。 |
3.访问控制
在每个文件的FCB(或索引结点)中增加一个访问控制列表(Access-Control List , ACL),该表中记录了各个用户可以对该文件执行哪些操作
读: | 从文件中读数据 |
写: | 向文件中写数据 |
执行: | 将文件装入内存并执行 |
添加: | 将新信息添加到文件结尾部分 |
删除: | 删除文件,释放空间 |
列表清单: | 列出文件名和文件属性 |
有的计算机可能会有很多个用户,因此访问控制列表可能会很大,可以用精简的访问列表解决这个问题:
在每个文件的FCB(或索引结点)中增加一个访问控制列表(Access-Control List , ACL),该表中记录了各个用户可以对该文件执行哪些操作。
精简的访问列表:以“组”为单位,标记各“组”用户可以对文件执行哪些操作。
如:分为系统管理员、文件主、文件主的伙伴、其他用户几个分组。当某用户想要访问文件时,系统会检查该用户所属的分组是否有相应的访问权限【系统需要管理分组的信息】
若想要让某个用户能够读取文件,只需要把该用户放入“文件主的伙伴”这个分组即可。
十、文件系统的层次结构
1.用户接口 | 文件系统需要向上层的用户提供一些简单易用的功能接口。这层就是用于处理用户发出的系统调用请求(Read、Write、Open、 Close 等系统调用) |
2.文件目录系统 | 用户是通过文件路径来访问文件的,因此这一层需要根据用户给出的文件路径找到相应的FCB或索引结点。所有和目录、目录项相关的管理工作都在本层完成,如:管理活跃的文件目录表、管理打开文件表等。 |
3.存取控制模块 | 为了保证文件数据的安全,还需要验证用户是否有访问权限。这一层主要完成了文件保护相关功能。 |
4.逻辑文件系统与文件信息缓冲区 | 用户指明想要访问文件记录号,这一层需要将记录号转换为对应的逻辑地址[记录转换到逻辑地址,例如读入索引块] |
5.物理文件系统 | 这一层需要把上一层提供的文件逻辑地址转换为实际的物理地址[地址转换] |
6.设备管理模块 | 直接与硬件交互,负责和硬件直接相关的一些管理工作。如:分配设备、分配设备缓冲区、磁盘调度、启动设备、释放设备等 |
7.辅助分配模块 | 负责文件存储空间的管理,即负责分配和回收存储空间 |
十一、文件系统的全局结构
1.新磁盘
2.物理格式化
也即低级格式化,划分扇区,检测坏扇区,并用备用扇区替换坏扇区【对操作系统透明】
3.逻辑格式化
磁盘分卷,完成各分区的文件系统初始化;
注:逻辑格式化后灰色部分已经有数据了。
4.文件系统在内存中的结构
文件open背后发生的内容:
例如打开M/A:
①系统找到外存中的目录M,读入内存;
②找到M中文件A的目录项,并复制到系统打开文件表;
③进程打开文件表中建立一个新目录项,索引到系统打开文件表,并返回文件描述符
十二、虚拟文件系统
一个普通的文件系统中可能会有不同的文件格式的文件系统,这样对其进行操作的参数可能不相同,而操作系统必须向上【用户】提供统一的接口。
所以这里引入了虚拟文件系统:
1.虚拟文件系统的特点
① | 向上层用户进程提供统一标准的系统调用接口,屏蔽底层具体文件系统的实现差异 |
② | VFS要求下层的文件系统必须实现某些规定的函数功能,如:open/read/write。一个新的文件系统想要在某操作系统上被使用,就必须满足该操作系统VFS的要求 |
③ | 每打开一个文件,VFS就在主存中新建一个vnode,用统一的数据结构表示文件,无论该文件存储在哪个文件系统。 |
注意: vnode只存在于主存中,而inode既会被调入主存,也会在外存中存储 | |
打开文件后,创建vnode,并将文件信息复制到vnode中,vnode的功能指针指向具体文件系统的函数功能。 |
2.文件挂载系统
文件系统挂载要做的事:
① | 在VFS中注册新挂载的文件系统。内存中的挂载表(mount table)包含每个文件系统的相关信息,包括文件系统类型、容量大小等。 |
② | 新挂载的文件系统,要向VFS提供一个函数地址列表 |
③ | 将新文件系统加到挂载点(mount point),也就是将新文件系统挂载在某个父目录下 |