前言
先这篇文章的原因在于前几天操作系统考试之前复习到文件系统那一块,发现书上关于目录,目录文件,索引结点这些说的十分模糊。光是看书完全没明白他在说什么,还好这块内容我在学习unix编程时接触过,这里特此做一个总结。
概述
文件包含数据,目录是文件的列表。不同的目录相互连接构成树状结构,目录还可以包含其他目录。那么如何理解文件在”一个目录中”? 硬盘实际上是一个金属圆盘,每个盘面上都有磁性物质,这些圆盘又是如何显示为一个包含文件,目录的树状结构呢。
从用户的角度看文件系统
从用户的角度来看,系统中硬盘里的文件组成了一颗目录树,每个目录包含了文件或者其他的目录。 我们可以通过常用的命令如: cd ,ls ,pwd 来查看目录或者文件的信息。很显然,文件的查看或者是更新都是任何一个操作系统都会提供的功能。 但是命令ln却并不常见,但却是unix里的一个基本操作。
假设我们输入以下命令
touch x
ln ./x ./xlink
ls > ./xlink
cat ./x
我们创建了一个文件叫做x,然后创建了一个链接指向了x文件,然后将ls的输出重定向给xlink的内容,那么当我们执行cat ./x的时候会发现输出了当前所在位置的文件信息。
从这些就可以大致了解了Unix的文件系统,硬盘上呈现了一个深度和广度都广泛延伸的目录树,Unix也提供了许多命令来和这种结构的对象一起工作。但他们是如何工作的?目录是什么?如何知道文件所处的目录?从一个目录转换到另一个目录意味着什么? pwd又是如何得知你当前的位置? 这些问题我们将继续探讨下去。
Unix文件系统内部结构
硬盘的实质其实是由磁性盘片组成的计算机系统的一个设备。所谓的文件系统,其实就是对这个设备的多层抽象
第一层抽象 从磁盘到分区
一个磁盘能存储大量的数据,一个磁盘可被分成区,每个分区都可以看做是一个独立的磁盘
第二层抽象 从磁盘到块序列
一个磁盘由磁性盘片组成,每个盘片的表面被分为很多同心圆,这些同心圆称为磁道,每个磁道又进一步被分成扇区,每个扇区可以存储一定字节数的数据。例如常见的每个扇区是512字节。扇区是磁盘的基本存储单元。
第三层抽象 从块序列到三个区域的划分
文件系统可以用来存储文件内容,文件属性,和目录,这些不同类型的数据是如何存储在被编号的磁盘块上呢?Unix使用了一个简单的方法,将磁盘分成了三部分。
超级块
文件系统中的第一个块被称为超级快,这个块存放文件系统本身的结构信息
i节点表
每个文件都有一些属性,如大小,文件所有者和最近修改时间等。这些性质都被记录在一个称为i节点的结构中,所有的i节点有相同的大小,文件系统中的每个文件都有一个i节点。
数据区
文件的内容保存在这个区域,磁盘上所有的块的大小是相同的。如果文件包含了超过一个块的内容,则文件内容会存放在多个磁盘块中。 那么系统是如何跟踪这些独立的磁盘块?
文件系统的实现,创建文件
文件的内容和属性分区存放看起来很简单,但实际上是如何工作的额呢? 创建一个文件时又会发生什么?如果我输入命令
who > user
当这个命令完成时,文件系统增加了一个存放命令who输出内容的新文件。 创建一个新文件的主要操作如下。
- 存储属性,内核找到一个空的i结点,比如第47块,内核将文件的信息记录其中
- 存储数据,文件内容存储在数据区的块中,如627 200 992
- 记录分配情况,内核在i结点的磁盘分布区记录了上述块序列。
- 添加文件名到目录,新文件的文件名是user,unix内核将入口(47,user)添加到目录文件。
cat命令的工作原理
现在我们再回头看之前所打的cat命令。
cat ./x
- 内核首先在目录中寻找文件名,得到x记录所包含的i节点号
- 定位所得到的I节点并读取数据块编号
- 访问存储文件内容的数据块,通过上面两步,内核已经知道文件内容在哪些数据块以及他们的顺序。
理解目录
用户看到的文件系统是目录与子目录的集合,每个目录能够包含文件和子目录,每个子目录有一个父目录,在文件系统内部,目录是一个包含文件名与i节点对的列表的文件。从用户的角度看到的是一个文件名的列表,而从Unix的角度看到的是一个被命名的指针的列表。
文件在目录中的真正含义
一般都说某个文件在某个目录中,但是现在已经知道目录中存放的只是文件在i节点表的入口,而文件的内容则存储在数据区内,文件在某个目录中,从用户的角度看文件y在目录demodir中,而从系统角度来看,看到的则是目录中有一个包含文件名y和i节点为491的入口。
简单的说,目录包含的是文件的引用,每个引用被称为连接,文件的内容存储在数据块,文件的属性则被记录在i节点的结构中,i节点的编号和文件名存储在目录中。目录包含子目录也同样如此。
目录包含子目录的真正含义
从用户的角度看a目录是demodir目录的一个子目录。实际上demodir包含一个指向那个子目录i节点的连接。从系统角度看,最上面一个表包含名为a指向277节点的连接。如何知道277是左边那个目录的i结点号呢? 内核在每个目录中都设置了目录本身的一个i节点号的入口,称为”.” 。 子目录的父目录同理。
文件名
在Unix的文件系统中,文件没有文件名,但是链接具有名字。文件仅仅拥有i节点号。