G
N
I
D
A
O
L

【操作系统-文件】文件层次结构

前排提示:本文部分借鉴或搬运了一些优秀博文的内容,仅为个人学习所用,请见谅!

1 用户接口(文件操作)

1.1 创建文件(create 系统调用)

过程如下:

  • 在外存中找到文件所需的空间。
  • 根据文件存放路径的信息找到该目录对应的目录文件,在目录中创建该文件对应的目录项。目录项中包含了文件名、文件在外存中的存放位置等信息。

1.2 删除文件(delete 系统调用)

过程如下:

  • 根据文件存放路径找到相应的目录文件,从目录中找到文件名对应的目录项。
  • 根据该目录项记录的文件在外存的存放位置、文件大小等信息,回收文件占用的磁盘块。
  • 从目录表中删除文件对应的目录项。

1.3 打开文件(open 系统调用)

(1)过程如下:

  • 根据文件存放路径找到相应的目录文件,从目录中找到文件名对应的的目录项,并检查该用户是否有指定的操作权限。
  • 将目录项复制到内存中的“打开文件表”中。并将对应表目的编号返回给用户。之后用户使用打开文件表的编号来指明要操作的文件。
  • 系统打开文件表对应表项的打开计数器 count 加 1。

(2)打开文件表(假设用户进程 A 已经打开了 test.txt,现在用户进程 B 打开 test.txt):

  • 系统的打开文件表(整个系统只有一张):
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 打开计数器:记录此时有多少个进程打开了此文件。
编号 文件名 ... 外存地址 打开计数器
1 ... ... ... ...
... ... ... ... ...
10 test.txt ... ... 2
... ... ... ... ...
  • 用户进程 A 的打开文件表
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 读/写指针:记录了该进程对文件的读/写操作进行到的位置。
编号 文件名 读写指针 访问权限 系统表索引号
1 ... ... ... ...
2 test.txt ... 只读 10
3 ... ... ... ...
  • 用户进程 B 的打开文件表
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 读/写指针:记录了该进程对文件的读/写操作进行到的位置。
编号 文件名 读写指针 访问权限 系统表索引号
1 test.txt ... 读和写 10

【注】虽然各个进程指向的是同一个文件,但每个进程的文件描述符都不相同。

1.4 关闭文件(close 系统调用)

(1)过程如下:

  • 将进程的打开文件表相应表项删除。
  • 回收分配给该文件的内存空间等资源。
  • 系统打开文件表对应表项的打开计数器 count 减 1,若 count = 0,则删除对应表项。

(2)打开文件表(假设用户进程 A 和 B 已经打开了 test.txt,现在用户进程 B 关闭 test.txt):

  • 系统的打开文件表(整个系统只有一张):
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 打开计数器:记录此时有多少个进程打开了此文件。
编号 文件名 ... 外存地址 打开计数器
1 ... ... ... ...
... ... ... ... ...
10 test.txt ... ... 1
... ... ... ... ...
  • 用户进程 A 的打开文件表
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 读/写指针:记录了该进程对文件的读/写操作进行到的位置。
编号 文件名 读写指针 访问权限 系统表索引号
1 ... ... ... ...
2 test.txt ... 只读 10
3 ... ... ... ...
  • 用户进程 B 的打开文件表(关闭文件 test.txt 后为空):
    • 编号:为打开文件表的索引,UNIX 称为文件描述符,Windows 称为文件句柄
    • 读/写指针:记录了该进程对文件的读/写操作进行到的位置。
编号 文件名 读写指针 访问权限 系统表索引号

【注】虽然各个进程指向的是同一个文件,但每个进程的文件描述符都不相同。

1.5 读文件(read 系统调用)

需要的参数:

  • 打开文件表中的索引号(即文件描述符,“读/写文件”用“文件描述符”即可指明文件,不再需要用到“文件名”)
  • 要读入多少数据(如:读入 1KB)
  • 读入的数据要放在内存中的什么位置

操作系统在处理 read 系统调用时,会从读指针指向的外存中,将用户指定大小的数据读入用户指定的内存区域中。

1.6 写文件(write 系统调用)

需要的参数:

  • 打开文件表中的索引号(即文件描述符,“读/写文件”用“文件描述符”即可指明文件,不再需要用到“文件名”)
  • 要写出多少数据(如:写出 1KB)
  • 写回外存的数据放在内存中的什么位置

操作系统在处理 write 系统调用时,会从用户指定的内存区域中,将指定大小的数据写回写指针指向的外存。

1.7 相关例题

【例 1】若一个用户进程通过 read 系统调用读取一个磁盘文件中的数据,则下列关于此过程的叙述中,正确的是( )

Ⅰ. 若该文件的数据不在内存,则该进程进入睡眠等待状态

Ⅱ. 请求 read 系统调用会导致 CPU 从用户态切换到核心态

Ⅲ. read 系统调用的参数应包含文件的名称

A. Ⅰ、Ⅱ

B. Ⅰ、Ⅲ

C. Ⅱ、Ⅲ

D. Ⅰ、Ⅱ、Ⅲ

【解】若该文件的数据不在内存,则系统需要对磁盘进行 I/O 操作,先入核心态,进程进入阻塞态,I、II 正确。

read 系统调用的参数应包含文件描述符,即打开文件表中的索引号,III 错误。

【例 2】若多个进程共享同一个文件 F,则下列叙述中正确的是( )

A、各进程只能用“读”方式打开文件 F

B、在系统打开文件表中仅有一个表项包含 F 的属性

C、各进程的用户打开文件表中关于 F 的表项内容相同

D、进程关闭 F 时系统删除 F 在系统打开文件表中的表项

【解】A 项显然不对。

B 项,整个系统只有一张系统打开文件表,显然正确。

C 项,不同进程的打开文件表的文件描述符都是不一样的,除此之外访问权限也不一样。

D 项,当有多个进程时,其中某一个进程关闭文件,并不会使系统删除打开文件表中的对应表项。

2 文件目录系统

2.1 文件控制块(FCB)

FCB 中包含了文件的基本信息(文件名、物理地址、逻辑结构、物理结构等),存取控制信息(是否可读/可写、禁止访问的用户名单等),使用信息(如文件的建立时间、修改时间等)。

FCB 的有序集合称为“文件目录”,一个 FCB 就是一个文件目录项。下面就是一个 FCB,也是一个文件目录项:

文件名 类型 存取权限 …… 物理位置
微信截图 PNG 只读 外存 995 号块

一个文件目录也被视为一个文件,称为目录文件

2.2 索引结点(i 结点)

Unix 系统采用将文件名和文件描述信息分开的方法,在文件目录中的每个目录项仅由文件名和索引结点指针组成,因此目录项的长度大幅减小,每个磁盘块可以放更多的目录项,节省了空间;当系统寻找文件时,仅当文件名匹配时,才需要读出文件的其他信息,因而检索文件时磁盘 I/O 次数也减少了很多。

下面就是一个索引结点:

文件名 索引结点指针
微信截图 指向索引结点(包含除了文件名之外的文件描述信息)

【注】存放在外存中的索引结点称为“磁盘索引结点”,每个文件有唯一的一个磁盘索引结点。当索引结点放入内存后称为“内存索引结点”,当文件被打开后,要将磁盘索引结点拷贝到内存的索引结点中,便于以后使用。

2.3 文件目录结构

2.3.1 单级目录结构

早期操作系统并不支持多级目录,整个系统中只建立一张目录表,每个文件占一个目录项。

单级目录实现了“按名存取”,但是不允许文件重名。因此,单级目录结构不适用于多用户操作系统。

  • 系统目录表
目录表
FCB1
FCB2
...
FCBn

2.3.2 两级目录结构

早期的多用户操作系统,采用两级目录结构。分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User Flie Directory)。

两级目录结构允许不同用户的文件重名,也可以在目录上实现实现访问限制(检查此时登录的用户名是否匹配),但不能对文件进行分类。

  • 系统目录表
用户名 用户文件目录的存放位置
User1 XXX
User2 XXX
User3 XXX
  • 用户目录表
User1 目录表
FCB1
FCB2
...
FCBn
User2 目录表
FCB1
FCB2
...
FCBn
User3 目录表
FCB1
FCB2
...
FCBn

2.3.3 多级目录结构(树形目录结构)

在多级目录结构中,不同目录下的文件可以重名。

  • 根目录
根目录
音乐(目录)
照片(目录)
微信截图(文件)
  • 子目录
音乐目录
111.mp3(文件)
222.mp3(文件)
333.mp3(文件)
照片目录
222.jpg(文件)
2015-08(目录)
自拍.jpg(文件)
  • 子目录的子目录
2015-08 目录
demo1.png(文件)
demo2.png(文件)
222.jpg(文件)
  • 路径访问
路径 描述 举例(访问文件 demo1.png) 读磁盘 I/O 操作
绝对路径 从根目录出发的路径 /照片/2015-08/demo1.png 3 次
相对路径 从当前目录出发的路径(在 Linux 中,“.”表示当前目录) (假设已经打开“照片”,则“照片”目录表已调入内存,当前目录为“照片”)./2015-08/demo1.png 2 次

2.3.4 无环图目录结构

可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。

每个共享文件/共享索引结点需设置一个链接计数变量 count,用于表示共享此文件的用户数,或用于表示链接到本索引结点上的用户目录项数。

  • count = 2:说明此时有两个用户目录项链接到该索引结点上,或者说是有两个用户在共享此文件。
  • count--:若某个用户决定“删除”该文件,则只是要把用户目录中与该文件对应的目录项删除,且索引结点的 count 值减 1。
  • count > 0:说明还有别的用户要使用该文件,暂时不能把文件数据删除,否则会导致指针悬空。
  • count = 0:系统负责删除文件。

【注】共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化。

  • 根目录
根目录
User1(目录)
User2(目录)
微信截图(文件)
  • 用户子目录
User1 目录
demo.jpg(指向同一个文件 pic.jpg
222.mp3(文件)
User2 目录
222.jpg(指向同一个文件 pic.jpg

(共享文件/共享索引结点 pic.jpg 的 count 为 2)

2.4 相关例题

【例 1】一个文件系统中,FCB 占 64B,一个盘块大小为 1KB,采用一级目录,假定文件目录中有 3200 个目录项,则查找一个文件平均需要( )次访问磁盘。

A. 50

B. 54

C. 100

D. 200

【解】一个盘块可以存储 1KB/64B = 16 个目录项,文件目录中有 3200 个目录项,则该文件目录占用 3200/16 = 200 个盘块。

因为一级目录的平均访盘次数为 1/2 盘块数(顺序查找目录表中的所有目录项,每个目录项为一个 FCB),所以查找一个文件平均需要 100 个盘块。

【例 2】某文件系统的目录项由文件名和索引节点号构成。若每个目录项长度为 64 字节,其中 4 字节存放索引节点号,60 字节存放文件名。文件名由小写英文字母构成,则该文件系统能创建的文件数量的上限为?

【解】最多文件数量由索引结点的个数决定。用 4 字节存放索引节点号,所以索引结点最多有 232 个,即最多可以存储 232 个文件。

3 存取控制模块

3.1 文件共享

项目 硬链接(基于索引结点的共享方式) 软链接(符号链接)
方式 索引结点指针-->索引结点(共享文件的路径)-->共享文件 索引结点指针-->索引结点(Link 类型文件的路径)-->Link 类型文件(共享文件的路径)-->共享文件
共享文件删除 并不是真的删除,只是要把用户目录中与该文件对应的目录项删除,且索引结点的 count 值减 1;只有当 count 为 0 时才会真正删除 共享文件被删除,但 Link 类型文件依然存在,只是通过 Link 类型文件中的路径去查找共享文件会失败

【注 1】共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化。

【注 2】由于软链接方式访问共享文件时要查询多级目录,会有多次磁盘 I/O,因此软链接方式的访问速度要比硬链接方式要慢。

【注 3】若软链接和硬链接同时指向同一个文件,则创建一个硬链接,该文件的 count 值先加 1,然后再复制该文件的 count 值作为硬链接的 count 值 ;创建一个软链接,则软链接的 count 值是从该文件的 count 值直接复制而来。

3.2 文件保护

方式 描述 优点 缺点
口令保护 为文件设置一个“口令”,用户请求访问该文件时必须提供“口令” 实现开销小 由于口令存放在文件对应的 FCB 或索引结点中,因此不太安全
加密保护 使用“密码”对文件进行加密,在访问文件时需要提供正确的“密码”才能对文件进行正确的解密 保密性强,不需要在系统中存储“密码”,只需一个加密/解密程序即可 加密/解密要花费一定时间
访问控制 在每个文件的 FCB(或索引结点)中增加一个访问控制列表(ACL),该表中记录了各个用户对该文件的访问类型(读、写、执行、删除等) 实现灵活,可以实现复杂的文件保护 ~

访问矩阵(R 为读权限,W 为写权限,E 为执行权限):

用户进程 文件 F1 文件 F2 文件 F3 文件 F4
A R - - RW -
B R - - RWE
C RW -

【注】如果对某个目录进行了访问权限的控制,那也要对目录下的所有文件进行相同的访问权限控制。

3.3 相关例题

【例 1】设文件 F1 的当前引用计数值为 1,先建立 F1 的符号链接(软链接)文件 F2,再建立 F1 的硬链接文件 F3,然后删除 F1。此时,F2 和 F3 的引用计数值分别是多少?

【解】文件 F1 的当前引用计数值为 1,则建立 F1 的符号链接文件 F2 后,F2 直接复制引用计数值,所以其引用计数值为 1。

再建立 F1 的硬链接文件 F3,此时 F1 的引用计数值加 1,F3 再复制引用计数值,所以 F3 的引用计数值为 2。

删除 F1 后,F1 的引用计数值减 1,此时 F3 的引用计数值为 1,F2 直接复制引用计数值,所以其引用计数值也为 1。

【例 2】某文件系统中,针对每个文件,用户类别分为 4 类:安全管理员、文件主、文件主的伙伴、其他用户;访问权限分为5种:完全控制、执行、修改、读取、写入。若文件控制块中用二进制位串表示文件权限,为表示不同类别用户对一个文件的访问权限,则描述文件权限的位数至少应为( )

A. 5

B. 9

C. 12

D. 20

【解】可以把用户访问权限抽象为一个矩阵,行代表用户,列代表访问权限。这个矩阵有 4 行 5 列,1 代表 true,0 代表 false,所以需要 20 位,选 D。

可以参考在 Linux 系统中:

  • 有(用户 user,用户组 group,其他 other)三类用户
  • 有(可读 r,可写 w,可执行 x)三种权限

所以对于一个文件权限,可以表示为rwx,rw_,r__ ,前三个字符表示用户对该文件可读可写可执行,中间三个字符表示用户组对该文件可读可写但不可执行,最后三个字符表示其他对该文件只读,总共需要 3×3=9 位。

【心得】我当时做的时候认为一个用户只能一个身份,所以表示用户类别只需要 2 位,权限需要 5 位,所以一共需要 7 位。现在我发现为什么这个想法是错的了,因为一个文件要面对五类用户,而不是单纯特定一个用户;而我之前的想法是从用户的角度去思考,觉得用户只能使其中的一类,而不是从文件使用者的角度去思考,哦,原来文件要给这五类用户用,每类用户都拥有什么权限等等,所以错了。

【例 3】若文件 f1 的硬链接为 f2,两个进程分别打开 f1 和 f2,获得对应的文件描述符为 fd1 和 fd2,则下列叙述中,正确的是( )

Ⅰ.f1 和 f2 的读写指针位置保持相同

Ⅱ.f1 和 f2 共享同一个内存索引结点

Ⅲ.fd1 和 fd2 分别指向各自的用户打开文件表中的一项

A.仅Ⅲ

B.仅Ⅱ、Ⅲ

C.仅Ⅰ、Ⅱ

D.Ⅰ、Ⅱ和Ⅲ

【解】两个进程读写文件的指针可以不同,I 错误。

硬链接通过索引结点进行链接,一个文件拥有自己的索引结点号,存在多个文件名指向同一个索引结点的情况,II 正确。

对于同一个文件,不同进程有不同的文件描述符,III 正确。

4 逻辑文件系统(文件的逻辑结构)

4.1 无结构文件(流式文件)

无结构文件,即文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。如 Windows 操作系统中的 .txt 文件。无结构文件没有明显的结构特性,因此也不用探讨无结构文件的“逻辑结构”问题。

4.2 有结构文件(记录式文件)

有结构文件,即由一组相似的记录组成,又称“记录式文件”,每条记录又若干个数据项组成。如数据库表文件、excel 文件。一般来说,每条记录有一个数据项可作为关键字(作为识别不同记录的 ID)。

根据各条记录的长度(占用的存储空间)是否相等,可以分为:

  • 定长记录:各条记录的长度(占用的存储空间)相等。

    • 串结构:记录之间的顺序与关键字无关(通常按照记录存入的时间决定记录的顺序)。
    • 顺序结构:记录之间的顺序按关键字顺序排列。
  • 可变长记录:各条记录的长度(占用的存储空间)不等。

    • 串结构:记录之间的顺序与关键字无关(通常按照记录存入的时间决定记录的顺序)。
    • 顺序结构:记录之间的顺序按关键字顺序排列。

4.2.1 顺序文件

顺序文件,即文件中的记录逻辑上一个接一个地顺序排列,记录可以是定长的或可变长的。

各个记录在物理上可以顺序存储(类似于顺序表)或链式存储(类似于链表),这属于数据结构的范畴,顺序文件的结构大致如下:

  • 顺序存储的顺序文件在逻辑地址空间的情况
地址 0 1 2 ...
记录 记录 0 记录 1 记录 2 ...
  • 链式存储的顺序文件在逻辑地址空间的情况
地址 0 1 2 3 4 ...
记录 记录 1(指针:4) 记录 0(指针:0) (空) (空) 记录 2(指针:...) ...
记录类型 物理存储——顺序存储 物理存储——链式存储
定长记录——串结构 可以随机存取,不能快速找到某关键字的记录 不能随机存取(每次只能从第一个开始找)
定长记录——顺序结构 可以随机存取,可以快速找到某关键字的记录 不能随机存取(每次只能从第一个开始找)
可变长记录——串结构 不能随机存取(每次只能从第一个开始找) 不能随机存取(每次只能从第一个开始找)
可变长记录——顺序结构 不能随机存取(每次只能从第一个开始找) 不能随机存取(每次只能从第一个开始找)

【注 1】可变长记录需要显式地给出记录长度,定长记录不需要。

【注 2】定长记录的顺序文件,若物理上采用顺序存储,则可实现随机存取;若能再保证记录的顺序结构,则可实现快速检索(如折半查找)

【注 3】一般来说,考试题目中所说的“顺序文件”指的是物理上顺序存储的顺序文件。

4.2.2 索引文件

对于可变长记录的文件,可建立一张索引表以加快文件检索速度,每条记录对应一个索引项。索引表和主文件(逻辑文件)组成一个索引文件。

  • 索引表
索引号(关键字) 记录的长度 记录的指针
An Qi m0 (该记录对应的逻辑首地址)
An Kang m1 (该记录对应的逻辑首地址)
Bao Rong m2 (该记录对应的逻辑首地址)
Bao Zi m3 (该记录对应的逻辑首地址)
Ding Ding m4 (该记录对应的逻辑首地址)
Cao Cao m5 (该记录对应的逻辑首地址)
... ... ...
  • 主文件(逻辑文件)
姓名 其他属性
An Qi ...
An Kang ...
Bao Rong ...
Bao Zi ...
Ding Ding ...
Cao Cao ...
... ...

【注 1】索引表本身是定长记录的顺序文件,因此可以快速找到第 i 个记录对应的索引项。

【注 2】主文件中的记录在物理上可以离散地存放。

4.2.3 索引顺序文件

为了缩减索引表的表项长度,提出了索引顺序文件的方案。索引顺序文件中,同样会为文件建立一张索引表,但不同的是:并不是每个记录对应一个索引表项,而是一组记录对应一个索引表项。每个分组就是一个顺序文件,分组内的记录不必按关键字排序。索引表和各分组顺序文件(主文件)组成一个索引顺序文件。

  • 索引表
索引号(关键字) 分组的指针
An Qi 分组 1 的逻辑首地址
Bao Rong 分组 2 的逻辑首地址
Ding Ding ...
Cao Cao ...
... ...
  • 分组顺序文件 1
姓名 其他属性
An Qi ...
An Kang ...
  • 分组顺序文件 2
姓名 其他属性
Bao Rong ...
Bao Zi ...

【注 1】对于含有 N 条记录的顺序文件,平均查找次数是 N/2 次。

【注 2】假设 N 条记录分为 sqrt(N) 组,则索引表中有 sqrt(N) 个表项,每组顺序文件有 sqrt(N) 个记录。先在索引表查找关键字,需要 sqrt(N)/2 次;再在对应的分组顺序文件顺序查找记录,需要 sqrt(N)/2 次。因此总共需要查找 sqrt(N)/2+sqrt(N)/2 = sqrt(N) 次。这也是最好的情况。

4.2.4 多级索引顺序文件

为了进一步提高检索效率,可以为顺序文件建立多级索引表。各级索引表和各分组顺序文件(主文件)组成一个多级索引顺序文件。

  • 顶级索引顺序表
索引号(关键字) 分组的指针
A 低级索引顺序文件的逻辑首地址
B 分组 3 (B)的逻辑首地址
C ...
D ...
... ...
  • 低级索引顺序表
索引号(关键字) 分组的指针
A 分组 1 (A)的逻辑首地址
An 分组 2 (An)的逻辑首地址
... ...
  • 分组顺序文件 1(A)
姓名 其他属性
A Tang ...
A Ming ...
  • 分组顺序文件 2(An)
姓名 其他属性
An Qi ...
An Kang ...
  • 分组顺序文件 3(B)
姓名 其他属性
Bao Rong ...
Bao Zi ...

4.3 相关例题

【例 1】某顺序文件含有 10000 个记录,平均查找的记录数为 5000 个。若采用索引顺序文件结构,则最好情况下平均只需查找( )次记录。

A.1000

B.10000

C.100

D.500

【解】10000 条记录分为 sqrt(10000) = 100 组,则索引表中有 100 个表项,每组顺序文件有 100 个记录。先在索引表查找关键字,需要 100/2 = 50 次;再在对应的分组顺序文件顺序查找记录,需要 100/2 = 50 次。因此总共需要查找 50+50 = 100 次。这也是最好的情况,选 C。

5 物理文件系统(文件的物理结构)

  • 磁盘块:磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”,磁盘块的大小与内存块、页面的大小相同。内存与磁盘之间的数据交换(即读/写操作、磁盘 I/O)都是以“块”为单位进行的。即每次读入一块,或每次写出一块。
  • 文件块:在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空间也被分为了一个一个的文件“块”。

【注 1】在 Windows 系统中称为“磁盘簇”“文件簇”,在 UNIX 系统中称为“磁盘块”“文件块”。

【注 2】簇是文件的分配单位,簇是操作系统使用的逻辑概念,扇区是磁盘上最小的物理单元。

于是文件的逻辑地址也可以表示为(逻辑块号,块内地址)的形式。

5.1 连续分配

连续分配方式要求每个文件在磁盘上占有一组连续的块,逻辑上相邻的块物理上也相邻

  • 文件目录:记录存放的起始块号和长度(总共占用几个块)。
文件名 ... 起始块号 长度
aaa ... 4 3
bbb ... 10 4
  • 磁盘
磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块) 磁盘块号 1(空闲磁盘块) 磁盘块号 2(空闲磁盘块) 磁盘块号 3(空闲磁盘块)
磁盘块号 4(aaa 逻辑块号 0 磁盘块号 5(aaa 逻辑块号 1 磁盘块号 6(aaa 逻辑块号 2 磁盘块号 7(空闲磁盘块)
磁盘块号 8(空闲磁盘块) 磁盘块号 9(空闲磁盘块) 磁盘块号 10(bbb 逻辑块号 0 磁盘块号 11(bbb 逻辑块号 1
磁盘块号 12(bbb 逻辑块号 2 磁盘块号 13(bbb 逻辑块号 3 磁盘块号 14(空闲磁盘块) 磁盘块号 15(空闲磁盘块)
  • 物理块号 = 起始块号 + 逻辑块号
  • 优点:支持顺序访问和直接访问(即随机访问);连续分配的文件在顺序访问时速度最快。
  • 缺点:不方便文件拓展;存储空间利用率低,会产生磁盘碎片。

【注】随机存取/随机访问:

  • 文件的某种逻辑结构支持随机存取/随机访问:采用这种逻辑结构的文件,可以根据记录号直接算出该记录对应的逻辑地址 (逻辑块号,块内地址)。
  • 文件的某种物理结构支持随机存取/随机访问:采用这种物理结构的文件,可以根据逻辑地址(逻辑块号,块内地址)直接算出该记录对应的物理地址。

5.2 链接分配

链接分配采取离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种。

5.2.1 隐式链接分配(默认)

  • 文件目录:记录存放的起始块号和结束块号。
文件名 ... 起始块号 结束块号
aaa ... 4 10
  • 磁盘:除了文件的最后一个磁盘块之外,每个磁盘块中都会保存指向下一个盘块的指针,这些指针对用户是透明的,因此被称为隐式链接分配。

文件 aaa:磁盘块号 4-->磁盘块号 6-->磁盘块号 5-->磁盘块号 12-->磁盘块号 8-->磁盘块号 10

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块) 磁盘块号 1(空闲磁盘块) 磁盘块号 2(空闲磁盘块) 磁盘块号 3(空闲磁盘块)
磁盘块号 4(aaa 逻辑块号 0【指针:磁盘块号 6】 磁盘块号 5(aaa 逻辑块号 2【指针:磁盘块号 12】 磁盘块号 6(aaa 逻辑块号 1【指针:磁盘块号 5】 磁盘块号 7(空闲磁盘块)
磁盘块号 8(aaa 逻辑块号 4【指针:磁盘块号 10】 磁盘块号 9(空闲磁盘块) 磁盘块号 10(aaa 逻辑块号 5 磁盘块号 11(空闲磁盘块)
磁盘块号 12(aaa 逻辑块号 3【指针:磁盘块号 8】 磁盘块号 13(空闲磁盘块) 磁盘块号 14(空闲磁盘块) 磁盘块号 15(空闲磁盘块)
  • 优点:很方便文件拓展,不会有碎片问题,外存利用率高。
  • 缺点:只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量的存储空间。

【注】考试题目中遇到未指明隐式/显式的“链接分配”,默认指的是隐式链接的链接分配。

5.2.2 显式链接分配

  • 文件目录:记录存放的起始块号。
文件名 ... 起始块号
aaa ... 4
bbb ... 2
  • 文件分配表(FAT):把用于链接文件各物理块的指针显式地存放在一张表中。-2 表示空闲磁盘块,而用 -1 表示文件结尾块。
物理块号 下一块
0 -2
1 -2
2 14
3 -2
4 6
5 12
6 5
7 -1
8 10
9 -2
10 -1
11 -2
12 8
13 -2
14 7
15 -2
  • 磁盘:每个磁盘块中不再保存指向下一个盘块的指针。

文件 aaa:磁盘块号 4-->磁盘块号 6-->磁盘块号 5-->磁盘块号 12-->磁盘块号 8-->磁盘块号 10

文件 bbb:磁盘块号 2-->磁盘块号 14-->磁盘块号 7

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块) 磁盘块号 1(空闲磁盘块) 磁盘块号 2(bbb 逻辑块号 0 磁盘块号 3(空闲磁盘块)
磁盘块号 4(aaa 逻辑块号 0 磁盘块号 5(aaa 逻辑块号 2 磁盘块号 6(aaa 逻辑块号 1 磁盘块号 7(bbb 逻辑块号 2
磁盘块号 8(aaa 逻辑块号 4 磁盘块号 9(空闲磁盘块) 磁盘块号 10(aaa 逻辑块号 5 磁盘块号 11(空闲磁盘块)
磁盘块号 12(aaa 逻辑块号 3 磁盘块号 13(空闲磁盘块) 磁盘块号 14(bbb 逻辑块号 1 磁盘块号 15(空闲磁盘块)
  • 优点:很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接来说,地址转换时不需要访问磁盘,因此文件的访问效率更高。
  • 缺点:文件分配表的需要占用一定的存储空间。
  • 不同的 FAT 文件系统
    • 早期的 FAT12:每个 FAT 表项为 12 位,所以 FAT 表最多可以记录 4096(212)个表项。每个盘块(即扇区)大小为 512B,则一个磁盘分区容量为 212 * 512B = 2MB。一个物理磁盘支持 4 个逻辑分区,所以允许的最大磁盘容量为 8MB。
    • 引入簇概念的 FAT12:由于一个扇区太小,不便于应付更大的磁盘容量,因此引入了簇的概念。一个簇可以包含 1 个、2 个、4 个或 8 个扇区。簇的大小可以人为设置,当设置一个簇有 8 个扇区时,一个磁盘分区容量为 212 * 512B * 8 = 16MB。一个物理磁盘支持 4 个逻辑分区,所以允许的最大磁盘容量为 64MB。
    • FAT16:每个 FAT 表项为 16 位,所以 FAT 表最多可以记录 65536(216)个表项。一个簇可以包含 1 个、2 个、4 个、···、64 个扇区。当设置一个簇有 64 个扇区时,一个磁盘分区容量为 216 * 512B * 64 = 2GB。
    • FAT32:每个 FAT 表项为 32 位。FAT32 规定:若磁盘分区不超过 8GB,则每个簇的大小为 8 个扇区(4KB);若磁盘分区在 8GB 至 16GB,则每个簇的大小为 16 个扇区(8KB);若磁盘分区在 16GB 至 32GB,则每个簇的大小为 32 个扇区(16KB);若磁盘分区不超过 32GB,则每个簇的大小为 64 个扇区(32KB)。

【注 1】一个磁盘仅设置一张 FAT。开机时,将 FAT 读入内存,并常驻内存。

【注 2】注意到 FAT 还标记了空闲的磁盘块,因此操作系统可以通过 FAT 对文件存储空间进行管理。

5.3 索引分配

索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块,即记录了逻辑块号到物理块号的映射关系(原理类似于页表)

索引表存放的磁盘块称为索引块,文件数据存放的磁盘块称为数据块

5.3.1 索引分配

  • 文件目录:记录存放的索引块的位置。
文件名 ... 索引块
aaa ... 2
  • 文件索引表(逻辑块号不属于索引表的一部分):
(逻辑块号) 物理块号(磁盘块号)
(0) 4
(1) 6
(2) 5
(3) 12
(4) 8
(5) 10
  • 磁盘

文件 aaa:磁盘块号 4-->磁盘块号 6-->磁盘块号 5-->磁盘块号 12-->磁盘块号 8-->磁盘块号 10

文件 aaa 索引表:磁盘块号 2

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块) 磁盘块号 1(空闲磁盘块) 磁盘块号 2(aaa 索引块 磁盘块号 3(空闲磁盘块)
磁盘块号 4(aaa 逻辑块号 0 磁盘块号 5(aaa 逻辑块号 2 磁盘块号 6(aaa 逻辑块号 1 磁盘块号 7(空闲磁盘块)
磁盘块号 8(aaa 逻辑块号 4 磁盘块号 9(空闲磁盘块) 磁盘块号 10(aaa 逻辑块号 5 磁盘块号 11(空闲磁盘块)
磁盘块号 12(aaa 逻辑块号 3 磁盘块号 13(空闲磁盘块) 磁盘块号 14(空闲磁盘块) 磁盘块号 15(空闲磁盘块)
  • 优点:支持随机访问,易于实现文件的拓展。
  • 缺点:索引表需占用一定的存储空间。访问数据块前需要先读入索引块。若采用链接方案,查找索引块时可能需要很多次读磁盘操作。

【注】注意区分索引文件的索引表索引分配的索引表

  • 索引文件的索引表:用户自己建立的,映射关系为从关键字到记录存放的逻辑地址。
  • 索引分配的索引表:操作系统建立的,映射关系为从逻辑块号到物理块号。

5.3.2 链接方案

如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。

  • 文件目录:记录存放的索引块的位置。
文件名 ... 索引块
aaa ... 2
  • 文件索引表 1(逻辑块号不属于索引表的一部分):
(逻辑块号) 物理块号(磁盘块号)
(0) 4
(1) 6
(2) 5
(3) 12
(4) 8
(5) 10
... ...
(255) (指向文件索引表 2)
  • 文件索引表 2(逻辑块号不属于索引表的一部分):
(逻辑块号) 物理块号(磁盘块号)
(256) ...
(257) ...
... ...
(511) ...
  • 磁盘

文件 aaa:磁盘块号 4-->磁盘块号 6-->磁盘块号 5-->磁盘块号 12-->磁盘块号 8-->磁盘块号 10-->...

文件 aaa 索引表:磁盘块号 2-->磁盘块号 15

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块) 磁盘块号 1(空闲磁盘块) 磁盘块号 2(aaa 索引块 1 磁盘块号 3(空闲磁盘块)
磁盘块号 4(aaa 逻辑块号 0 磁盘块号 5(aaa 逻辑块号 2 磁盘块号 6(aaa 逻辑块号 1 磁盘块号 7(空闲磁盘块)
磁盘块号 8(aaa 逻辑块号 4 磁盘块号 9(空闲磁盘块) 磁盘块号 10(aaa 逻辑块号 5 磁盘块号 11(空闲磁盘块)
磁盘块号 12(aaa 逻辑块号 3 磁盘块号 13(空闲磁盘块) 磁盘块号 14(空闲磁盘块) 磁盘块号 15(aaa 索引块 2

5.3.3 多层索引

建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。

image

【注】采用 K 层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要 K + 1 次读磁盘操作;若顶级索引表已调入内存,则访问一个数据块只需要 K 次读磁盘操作。

5.3.4 混合索引

多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表) 。

image

5.4 相关例题

【例 1】设文件索引结点中有 7 个地址项,其中 4 个地址项是直接地址索引,2 个地址项是一级间接地址索引,1 个地址项是二级间接索引,每个地址项大小为 4B,若磁盘索引块和磁盘数据块大小均为 256B,则可表示的单个文件最大长度是?

【解】一个磁盘索引块可以存储 256B/4B = 64 个地址项。

  • 4 个地址项是直接地址索引:可以表示的长度为 4*256B = 1024B = 1KB
  • 2 个地址项是一级间接地址索引:可以表示的长度为 2*64*256B = 32KB
  • 1 个地址项是二级间接索引:可以表示的长度为 1*64*64*256B = 1024KB

所以可表示的单个文件最大长度是 1KB+32KB+1024KB = 1057KB。

【例 2】文件系统采用两级索引分配方式。如果每个磁盘块的大小为 2KB,每个盘块号占 4B,则该系统中单个文件的最大长度是( )。

A.64MB

B.128MB

C.256MB

D.512MB

【解】一个磁盘索引块可以存储 2KB/4B = 0.5K 个地址项。

该系统中单个文件的最大长度是 0.5K*0.5KB*2KB = 0.5*230B = 0.5 GB = 512MB。

【例 3】设某文件为索引顺序文件,由 5 个逻辑记录组成,每个逻辑记录的大小与磁盘块的大小相等,均为 512B,并依次存放在 50, 121, 75, 80, 63 号磁盘块上。若要存取文件的第 1569 逻辑字节处的信息,则要访问( )号磁盘块。

A. 3

B. 75

C. 80

D. 63

【解】1569B/512B = 3.06 = 4 ,即第 1569 逻辑字节位于第 4 个逻辑分区,所以要访问 80 号磁盘块。

【例 4】在文件的索引节点中存放直接索引指针 10 个,一级和二级索引指针各 1 个。磁盘块大小为 1KB,每个索引指针占 4 个字节。若某文件的索引节点已在内存中,则把该文件偏移量(按字节编址)为 1234 和 307400 处所在的磁盘块读入内存,需访问的磁盘块个数分别是?

【解】一个磁盘索引块可以存储 1KB/4B = 28 = 256 个地址项。

  • 10 个地址项是直接地址索引:可以表示的长度为 10*1KB = 10KB
  • 1 个地址项是一级索引:可以表示的长度为 1*28*1KB = 256KB
  • 1 个地址项是二级索引:可以表示的长度为 1*28*28*1KB = 216KB = 64MB

文件偏移量为 1234B < 10KB,对应直接地址索引。因为某文件的索引节点已在内存中,需访问的磁盘块个数是 1。

文件偏移量为 307400B/1024B = 300KB > 256KB,对应二级地址索引。因为某文件的索引节点已在内存中,需访问的磁盘块个数是 3。

6 辅助分配模块(文件存储空间管理)

6.1 存储空间的划分与初始化

  • 存储空间的划分:为磁盘分区,将物理磁盘划分为一个个文件卷(或称为逻辑卷、逻辑盘)。

  • 存储空间的初始化:将各个文件卷划分为目录区、文件区。

    • 目录区:主要存放文件目录信息(FCB)、用于磁盘存储空间管理的信息。
    • 文件区:用于存放文件数据。

6.2 存储空间的管理

6.2.1 空闲表法

  • 磁盘
磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块 磁盘块号 1(空闲磁盘块 磁盘块号 2(空闲磁盘块 磁盘块号 3(空闲磁盘块
磁盘块号 4(aaa 逻辑块号 0) 磁盘块号 5(aaa 逻辑块号 1) 磁盘块号 6(aaa 逻辑块号 2) 磁盘块号 7(空闲磁盘块
磁盘块号 8(空闲磁盘块 磁盘块号 9(空闲磁盘块 磁盘块号 10(bbb 逻辑块号 0) 磁盘块号 11(bbb 逻辑块号 1)
磁盘块号 12(bbb 逻辑块号 2) 磁盘块号 13(bbb 逻辑块号 3) 磁盘块号 14(空闲磁盘块 磁盘块号 15(空闲磁盘块
  • 空闲盘块表:(适用于连续分配)
第一个空闲盘块号 空闲盘块数
0 4
7 3
14 2

【注 1】与内存管理中的动态分区分配很类似,为一个文件分配连续的存储空间。同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。

【注 2】与内存管理中的动态分区分配很类似,当回收某个存储区时需要有四种情况——①回收区的前后都没有相邻空闲区;②回收区的前后都是空闲区;③回收区前面是空闲区;④回收区后面是空闲区。

6.2.2 空闲链表法

  • 空闲盘块链:空闲盘块中存储着下一个空闲盘块的指针。(适用于离散分配)

空闲盘块链:0-->9-->14-->15-->1-->2-->7-->8-->3

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块【链头指针:磁盘块号 9】 磁盘块号 1(空闲磁盘块【指针:磁盘块号 2】 磁盘块号 2(空闲磁盘块【指针:磁盘块号 7】 磁盘块号 3(空闲磁盘块【链尾指针:无】
磁盘块号 4(aaa 逻辑块号 0) 磁盘块号 5(aaa 逻辑块号 1) 磁盘块号 6(aaa 逻辑块号 2) 磁盘块号 7(空闲磁盘块【指针:磁盘块号 8】
磁盘块号 8(空闲磁盘块【指针:磁盘块号 3】 磁盘块号 9(空闲磁盘块【指针:磁盘块号 14】 磁盘块号 10(bbb 逻辑块号 0) 磁盘块号 11(bbb 逻辑块号 1)
磁盘块号 12(bbb 逻辑块号 2) 磁盘块号 13(bbb 逻辑块号 3) 磁盘块号 14(空闲磁盘块【指针:磁盘块号 15】 磁盘块号 15(空闲磁盘块【指针:磁盘块号 1】

【注】分配空间和回收空间

  • 如何分配:若某文件申请 K 个盘块,则从链头开始依次摘下 K 个盘块分配,并修改空闲链的链头指针。
  • 如何回收:回收的盘块依次挂到链尾,并修改空闲链的链尾指针。
  • 空闲盘区链:连续的空闲盘块组成一个空闲盘区。空闲盘区中的第一个盘块内记录了盘区的长度、下一个盘区的指针。(适用于连续分配、离散分配)

空闲盘区链:(0,1,2,3)-->(14,15)-->(7,8,9)

磁盘块 磁盘块 磁盘块 磁盘块
磁盘块号 0(空闲磁盘块【指针:磁盘块号 14,盘区长度:4】 磁盘块号 1(空闲磁盘块 磁盘块号 2(空闲磁盘块 磁盘块号 3(空闲磁盘块
磁盘块号 4(aaa 逻辑块号 0) 磁盘块号 5(aaa 逻辑块号 1) 磁盘块号 6(aaa 逻辑块号 2) 磁盘块号 7(空闲磁盘块【指针:无,盘区长度:3】
磁盘块号 8(空闲磁盘块 磁盘块号 9(空闲磁盘块 磁盘块号 10(bbb 逻辑块号 0) 磁盘块号 11(bbb 逻辑块号 1)
磁盘块号 12(bbb 逻辑块号 2) 磁盘块号 13(bbb 逻辑块号 3) 磁盘块号 14(空闲磁盘块【指针:磁盘块号 7,盘区长度:2】 磁盘块号 15(空闲磁盘块

6.2.3 位示图法

每个二进制位对应一个盘块。“0”代表盘块空闲,“1”代表盘块已分配。位示图一般用连续的“字”来表示,字中的每一位对应一个盘块。因此可以用(字号,位号)对应一个盘块号。当然有的题目中也描述为(行号,列号)。

. 位号 0 位号 1 位号 2 ...
字号 0 0 1 0 ...
字号 1 1 1 0 ...
字号 2 1 0 0 ...
... ... ... ... ...

(1)已知字号(行号) i、位号(列号) j、字长 n,求盘块号 b

  • 字号从 1 开始,位号从 1 开始:
    • 盘块号从 1 开始:b = (i-1) * n + j
    • 盘块号从 0 开始:b = (i-1) * n + j - 1
  • 字号从 0 开始,位号从 0 开始:
    • 盘块号从 1 开始:b = i * n + (j+1)
    • 盘块号从 0 开始:b = i * n + (j+1) - 1

(2)已知盘块号 b、字长 n,求字号(行号) i、位号(列号) j

  • 字号从 1 开始,位号从 1 开始:
    • 盘块号从 1 开始:i = (b-1) / n + 1, j = (b-1) % n + 1
    • 盘块号从 0 开始:i = b / n + 1, j = b % n + 1
  • 字号从 0 开始,位号从 0 开始:
    • 盘块号从 1 开始:i = (b-1) / n, j = (b-1) % n
    • 盘块号从 0 开始:i = b / n, j = b % n

6.2.4 成组链接法

空闲表法、空闲链表法不适用于大型文件系统,因为空闲表或空闲链表可能过大。UNIX 系统中采用了成组链接法对磁盘空闲块进行管理。

文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。

6.3 相关例题

【例 1】假设字号从 1 开始,位号从 1 开始,若用 8 个字(字长 32 位)组成的位示图管理内存,假定用户归还一个块号为 100 的内存块时,它对应位示图的位置为?如果字号从 0 开始,位号从 0 开始呢?

【解】(1)字号从 1 开始,位号从 1 开始:

首先计算是第几个字:(100-1) / 32 = 3.05,说明是第 4 个字号。

再计算是第几个位号:(100-1) % 32 = 4,说明是第 4 个位号。

所以字号是 4,位号是 4。

(2)字号从 0 开始,位号从 0 开始:

首先计算是第几个字:(100-1) / 32 = 3.05,说明是第 4 个字号。

再计算是第几个位号:(100-1) % 32 = 4,说明是第 4 个位号。

所以字号是 3,位号是 3。

【例 2】文件系统用位图法表示磁盘空间的分配情况,位图存于磁盘的 32-127 号块中,每个盘块占 1024B,盘块和块内字节均从 0 开始编号。假设要释放的盘块号为 409612,则位图中要修改的位所在的盘块号和块内字节序号分别是?

【解】因为一个磁盘块大小为 1024B*8bit = 8192 位,即表示一个磁盘中可以表示 8192 位,位图法是使用一个位表示一个磁盘块的使用情况,故而在第 32 号磁盘块可以表示的磁盘块是(0~8191 号磁盘块,从 0 开始编号),第 33 号磁盘块则表示(8192 ~ 8192+8191=16383 号),其他依此类推。

计算出该盘块号位于第几个盘块:409612 / (1024*8) = 50.01,说明是第 51 个盘块,因此盘块号为 32+51-1 = 82。

块内偏移 = 409612 % (1024*8) = 12,12 / 8 = 1.5,说明块内偏移了两个字节,因此块内字节序号为 1。

如果盘块和块内字节均从 1 开始编号,那么盘块号是 82,块内字节序号为 2。

【例 3】下列选项中,可用于文件系统管理空闲磁盘块的数据结构是( )

I.位图

II.索引结点

III.空闲磁盘块链

IV.文件分配表(FAT)

A.仅 I、II

B.仅 I、III、IV

C.仅 I、III

D.仅 II、III、IV

【解】位图、空闲磁盘块链均可以管理空闲磁盘块。

索引结点位于 FCB 内,用于记录文件的信息,不能管理空闲磁盘块。

文件分配表(FAT)除了记录文件占用的磁盘块外,还记录了空闲磁盘块。所以选 B。

7 设备管理模块

直接与硬件交互,负责和硬件直接相关的一些管理工作。如:分配设备、分配设备缓冲区、磁盘调度、启动设备、释放设备等。

posted @ 2022-10-15 23:14  漫舞八月(Mount256)  阅读(665)  评论(0编辑  收藏  举报