OS 文件系统
操作系统中处理文件的部分称为文件系统(File System),文件系统包括为文件及管理文件的软件集合。
文件
文件命名
文件命名向用户提供了简单、直观的文件访问方式,使用户在访问文件时不必了解信息存储的方法、位置及磁盘实际动作方式等细节,而只需要给出要访问的文件名。
文件结构
- 无结构字节序列
无结构字节序列文件也称为流式文件。操作系统所见到的都是字节。在 UNIX 和 Windows 中都采用这种方式。
- 固定长度记录序列
构成文件的基本单位是具有固定长度的记录,每个记录都有其内部结构。
- 树形结构
文件由一棵记录树构成,记录长度不定,在记录的固定位置包含一个关键字域,记录树按关键字域排序。
文件类型
- ASCII 文件
ASCII(American Standard Code for Information Interchange)文件由多行正文组成,在某些系统中每行用回车符结束,某些则用换行符结束,而有些系统还同时采用回车符和换行符,如 MS-DOS。各行的长度不必相同。
ASCII 文件的明显优势是可以显示和打印,也可以用通常的文本编辑器进行编辑。另外,如果程序以 ASCII 文件作为输入和输出,就很容易把一个程序的输出作为另一个程序的输入。
- 二进制文件
二进制文件具有一定的内部结构,如可执行的 .exe
文件。
文件存取
用户通过对文件的存取来完成对文件的各种操作,文件的存取方式是由文件的性质和用户使用文件的情况确定的。常用的文件存取方式有两种:顺序存取和随机存取。
文件属性
属性 | 含义 |
---|---|
保护 | 谁可以存取文件,以什么样的方式存取文件 |
口令 | 存取文件需要的口令 |
创建者 | 创建文件者的 ID |
所有者 | 当前所有者 |
只读标志 | 0 表示读/写;1 表示只读 |
隐藏标志 | 0 表示正常;1 表示不在列表中显示 |
系统标志 | 0 表示普通文件;1 表示系统文件 |
存档标志 | 0 表示已经备份;1 表示需要备份 |
文件操作
- CREATE:该操作完成创建文件的功能,并设置文件的一些属性。
- DELETE:删除不用的文件并释放磁盘空间。
- OPEN:使用文件前,打开文件。
- CLOSE:关闭文件以释放内部表空间。
- READ:从文件中读取数据。
- WRITE:往文件中写数据。
- APPEND:是 WRITE 调用的限制形式,它只能在文件末尾添加数据。
- SEEK:对于随机存取文件,要指定从何处开始取数据。
- GETATTRIBUTES:获取文件属性。
- SETATTRIBUTES:设置文件某些属性。
- RENAME:修改已有文件的名称。
目录
目录是文件系统中实现 按名访问文件 的重要数据结构。
层次目录系统
- 目录文件的结构
目录文件有两种常见的结构:属性放在目录项中和放在 i
结点中。
- 目录结构
- 单层目录
单层目录使得软件设计相对简单。
在多用户系统中,单层目录带来的问题是,不同用户可能会使用相同的文件名。
在查找一个文件时必须对单层目录表中的所有文件信息项进行搜索,因此搜索效率也较低。
- 两级目录
两级目录结构中,目录被分为两级,第一级称为主目录,给出了用户名和用户子目录所在的物理位置。第二级称为用户目录,给出了该用户所有文件的文件控制块。
两级目录的优点是解决了文件的重名问题和文件共享问题,查找时间降低。缺点是增加了系统的存储开销。
- 树形目录
最高层为根目录,最底层为文件。
树形目录的优点是便于文件的分类,层次结构清晰,便于管理和保护,解决了重名问题,查找速度加块。缺点是查找一个文件按路径名逐层检查,由于每个文件都放在外存中,多次访问磁盘会影响速度,结构相对复杂。
路径名
- 绝对路径名:由从根目录到文件的路径组成。
- 相对路径名:有两个特殊的目录项
.
(表示当前目录) 和..
(表示上一层目录)。
目录操作
- CREATE:根据给定的目录文件名,创建目录。
- DELETE:根据指定的目录名删除一个目录文件。
- OPENDIR:目录内容可以被读取。
- CLOSEDIR:读目录结束后,关闭目录以释放内部表空间。
- READDIR:以标准格式返回打开目录的下一级目录项。
- RENAME:更换目录名。
文件系统的实现
实现文件
- 连续分配
连续分配就是把每个文件作为一连串连续数据块存储在磁盘上。
连续分配有两个优点:
- 实现简单,记录每个文件用到的簇仅需存储两个数字即可:第一块的磁盘地址和文件的块数。给定第一块的簇号,就可以找到任何其他块的簇号。
- 读操作性能好,在单个操作中就能从磁盘上读取整个文件。
连续分配的缺点:随着时间的推移,磁盘会变得零碎。当删除文件时,文件所占的簇被释放,这些空闲的连续簇形成「空洞」。随着磁盘的使用,磁盘上的空洞就越多。
- 使用磁盘链接表的分配
为每个文件构造簇的链接表,每个簇开始的几个字节用于存放下一个簇的簇号,簇在其它部分存放数据,每个文件可以存放在不连续的簇中。在目录项中只需存放第一个数据块的磁盘地址,文件的其它块可以根据这个地址来查找。
使用磁盘链接表的分配的优点是可以充分利用每个簇,不会因为磁盘碎片(除了最后一块中的内部碎片)而浪费存储空间,管理也比较简单。缺点是随机存取相当缓慢。
- 使用内存的链接表分配
将文件所在的磁盘簇号存放在内存的表(文件分配表)中。访问文件时,只需从内存文件分配表中顺着某种链接关系查找簇的簇号。不管文件有多大,在目录项中只需记录文件的第一块数据所在簇的簇号,根据它查找到文件的所有块。MS-DOS 就使用这种方法进得磁盘分配。
使用内存的链接表分配的缺点是必须把整个表都存放在内存中。
i
结点
为每个文件赋予一个被称为 i
结点的数据结构,其中列出了文件属性和文件块的磁盘地址。
实现目录
- CP/M 中的目录
CP/M 是一个微机操作系统,它只有一层目录,因此只有一个目录文件。
字节 | 1 | 8 | 3 | 1 | 2 | 1 | 16 |
---|---|---|---|---|---|---|---|
名称 | 用户码 | 文件名 | 扩展名 | 范围 | 块数 | 磁盘块号 |
- 用户码:记录了文件所有者。
- 文件名:存放文件名。
- 扩展名:标识文件类型。
- 范围:由该域可知某目录项是文件的第几个目录项,因为一个很大的文件(大于 16KB),其簇的数量多,在一个目录项中记录不下。
- 块数:文件实际使用的簇的数量。
- 最后 16 个域记录了簇号。
- MS-DOS 中的目录
8 | 3 | 1 | 10 | 2 | 2 | 2 | 4 |
---|---|---|---|---|---|---|---|
文件名 | 扩展名 | 文件属性 | 保留 | 时间 | 日期 | 第一簇的簇号 | 长度 |
MS-DOS 用文件分配表即 FAT 作为索引表来存放文件数据所在簇的簇号。
FAT 文件系统有 3 个版本:FAT-12、FAT-16、FAT-32,取决于用多少个二进制位存放簇号。
- UNIX 中的目录
UNIX 中每个目录项只包含一个文件名及其 i
结点号。有关文件类型、长度、时间、所有者和簇号等信息都放在 i
结点中。
磁盘空间管理
- 簇大小
文件系统为文件分配磁盘空间是以 簇 为单位的,一旦用固定大小的簇来存储文件,就会出现一个问题:簇的大小应该是多少?簇太大,容易造成空间的浪费;簇大小,则会使访问文件的时间延长。
一般簇大小是 2 的整数次幂个连续的扇区,如 1 个扇区,512 个字节;连续两个扇区,大小为 1KB;连续 4 个扇区,大小为 2KB。根据系统管理的文件大小,可以选择合适的簇大小来格式化磁盘。
- 记录空闲块
- 空闲簇链接表:用一些空闲簇存放空闲簇的簇号。
- 位图:用
n
位位图对应磁盘的n
个簇,在位图中,空闲簇用1
表示,已分配簇用0
表示。