先上个大图
本篇属于计算机操作系统里面的文件系统管理部分知识,主要介绍共享文件的功能。
不过在此之前,需要对整个文件系统进行一个简单的概述,以便知道共享文件到底是在操作什么。
一个文件系统由目录,文件夹,文件组成;构成方式就是目录--->文件夹--->文件。
而这些文件系统的构成是经过磁盘分区形成的,这里不用去管磁盘分区是怎么做的,只需要知道,一个磁盘在经过GPT分区后,目前的Windows系统采用的是NTFS格式的文件系统,而Linux多采用的是ext4格式的文件系统。
对于Windows系统,给磁盘分完区后,每个磁盘目录就是顶级目录,如下图:
进入磁盘后就会有目录和文件夹,或者文件。然后里面还会有二级目录,再包含文件夹,文件等。
关于目录,这里有两个概念要介绍:
1.绝对路径:从顶级目录(根目录)开始,到当前文件所在的目录路径;比如 文件gcc.exe
它的绝对路径是:
F:\CodeBlocks20\CodeBlocks\MinGW\bin
2.相对路径:在包含当前文件的目录下的路径
\bin
Linux的分区不太一样,这里暂时不展开,感兴趣的可以自行百度一下。
文件命名
对于具体的每一个文件,根据它的文件后缀名不同而体现不同的功能。
比如:.txt表示它是文本文件,.exe表示它是可执行文件,.msi表示它是一个安装文件等等,还有许多不同的文件扩展名
文件属性
每一个文件都有自己的属性,包括文件创建时间,修改时间,文件大小等;用一个Windows下的文件举例,右键查看属性;
可以看到红色框内的就是它的属性
文件组成
上面知道了目录和文件的许多概念,但是当目录和文件过多的时候,文件系统又是怎么管理文件的呢?比如你要打开游戏,或者打开QQ这些软件,总不能每次跑到安装路径下去找可执行文件打开吧。这个时候,就需要对整个文件系统进行一些有序的管理,以便你能很快的找到或者打开文件。
文件系统会为每个文件分配两个数据结构:索引结点(index node)和 目录项(directory entry)
索引节点,也就是 inode,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间
目录项,也就是 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。
由于索引节点唯一标识一个文件,而目录项记录着文件的名,所以目录项和索引节点的关系是多对一,也就是说,一个文件可以有多个别字。
下面要提一下磁盘的一些概念:磁盘块/簇(虚拟出来的)。 块是操作系统中最小的逻辑存储单位。操作系统与磁盘打交道的最小单位是磁盘块。 通俗的来讲,在Windows下如NTFS等文件系统中叫做簇;在Linux下如Ext4等文件系统中叫做块(block)。
另外,磁盘进行格式化的时候,会被分成三个存储区域,分别是超级块、索引节点区和数据块区。 - 超级块,用来存储文件系统的详细信息,比如块个数、块大小、空闲块等等。 - 索引节点区,用来存储索引节点; - 数据块区,用来存储文件或目录数据;
整个文件系统和磁盘的关系如下图所示:
文件存储
我们知道一个文件是怎么组成的之后,就要知道它是怎么在磁盘中存储的。
文件的数据是要存储在硬盘上面的,数据在磁盘上的存放方式,就像程序在内存中存放的方式那样,有以下两种:
- 连续空间存放方式
- 非连续空间存放方式
其中,非连续空间存放方式又可以分为「链表方式」和「索引方式」
下面介绍索引方式,对于其他方式
索引的实现是为每个文件创建一个「索引数据块」,里面存放的是指向文件数据块的指针列表,说白了就像书的目录一样,要找哪个章节的内容,看目录查就可以。
另外,文件头需要包含指向「索引数据块」的指针,这样就可以通过文件头知道索引数据块的位置,再通过索引数据块里的索引信息找到对应的数据块。如下图所示:
但是当文件过大,达到一个索引数据块放不下索引信息时,就对它进行套娃(计算机系统的精髓所在),创建多级索引。
空闲空间管理
在将文件存储之后,我们总不可能恰到好处的使用了磁盘空间,不留一点缝隙,因此在文件存储之后,磁盘中总会产生一些空闲空间,当空闲空间变多的时候,就会影响磁盘的存储;这个时候就需要对这些空闲空间进行管理。而管理方式则有下面几种:
- 空闲表法
- 空闲链表法
- 位图法
空闲表法就是为所有空闲空间建立一张表,表内容包括空闲区的第一个块号和该空闲区的块个数,注意,这个方式是连续分配的。如下图:
我们也可以使用「链表」的方式来管理空闲空间,每一个空闲块里有一个指针指向下一个空闲块,这样也能很方便的找到空闲块并管理起来。如下图:
位图是利用二进制的一位来表示磁盘中一个盘块的使用情况,磁盘上所有的盘块都有一个二进制位与之对应。
当值为 0 时,表示对应的盘块空闲,值为 1 时,表示对应的盘块已分配。它形式如下:
1111110011111110001110110111111100111 ...
在 Linux 文件系统就采用了位图的方式来管理空闲空间,不仅用于数据空闲块的管理,还用于 inode 空闲块的管理,因为 inode 也是存储在磁盘的,自然也要有对其管理。
其实到此为止,一个文件从创建,构成,存储,空闲空间管理,似乎都有了对应的方式,但是它还缺少一些东西,那就是前面提到的,你不可能每次都到目录文件中去找可执行文件打开程序吧。
基于此,文件系统又提出了一种文件共享的方式:链接
文件共享
链接分为硬链接和软链接两种方式。
硬链接
- 具有相同inode节点号的多个文件互为硬链接文件;
- 删除硬链接文件或者删除源文件任意之一,文件实体并未被删除;
- 只有删除了源文件和所有对应的硬链接文件,文件实体才会被删除;
- 硬链接文件是文件的另一个入口;
- 可以通过给文件设置硬链接文件来防止重要文件被误删;
- 创建硬链接命令 ln 源文件 硬链接文件;
- 硬链接文件是普通文件,可以用rm删除;
- 对于静态文件(没有进程正在调用),当硬链接数为0时文件就被删除。注意:如果有进程正在调用,则无法删除或者即使文件名被删除但空间不会释放。
软链接
- 软链接类似windows系统的快捷方式;
- 软链接里面存放的是源文件的路径,指向源文件;
- 删除源文件,软链接依然存在,但无法访问源文件内容;
- 软链接失效时一般是白字红底闪烁;
- 创建软链接命令 ln -s 源文件 软链接文件;
- 软链接和源文件是不同的文件,文件类型也不同,inode号也不同;
- 软链接的文件类型是“l”,可以用rm删除。
总结一下:
- 硬链接: 与普通文件没什么不同,
inode
都指向同一个文件在硬盘中的区块 - 软链接: 保存了其代表的文件的绝对路径,是另外一种文件,在硬盘上有独立的区块,访问时替换自身路径。
到此,我们也解决了如何快速打开文件的问题。对于一个文件系统的描述已经差不多了。
上面介绍的都是文件,关于目录没怎么介绍,下面进行补充:
目录
我们其实可以把目录看成一个特殊的文件。
和普通文件不同的是,普通文件的块里面保存的是文件数据,而目录文件的块里面保存的是目录里面一项一项的文件信息。
在目录文件的块中,最简单的保存格式就是列表,就是一项一项地将目录下的文件信息(如文件名、文件 inode、文件类型等)列在表里
通常,第一项是「.
」,表示当前目录,第二项是「..
」,表示上一级目录,接下来就是一项一项的文件名和 inode。
为了提高查找效率,将保存目录的格式改成哈希表。
其实这里还有一层知识没有提到,那就是文件系统是属于操作系统来管理,那么用户是怎么去创建文件,打开/关闭,读/写文件等操作的呢?它就是虚拟文件系统VFS。为用户和操作系统提供一个统一的接口。
文章结尾附上参考链接:
https://zhuanlan.zhihu.com/p/183238194
希望传递知识的同时也能传递出作者的信息。