文章目录
什么是文件系统
我们之前所说的文件读写都是通过进程对已经打开的文件进行操作,也就是对操作系统对文件所创建的结构体进行操作
那么对于磁盘中没有打开的文件是如何进行管理的
磁盘的物理结构
这里我们主要讨论机械磁盘而非固态磁盘,因为机械磁盘的价格较低,而且学习之后也能更好的理解整个系统
这是机械硬盘内部的样子,有点像光盘的样子,不同的是光盘只能读,机械磁盘可以读写,而且机械磁盘是一摞的,利用这个磁头来感应出来0和1
绕着这个转轴,就是圆心,有不同的半径的圆,我们称之为磁道,同一个磁道所组成的称为柱面,而为了同时读取数据,按照不同的圆心角划分成了不同的扇区
我们可以把某一个磁道的扇区单独取出来,看成一个数组,这样就能把文件系统划分成众多这样的数组,再将其组织起来即可
这样对磁盘问题就变成了对数组的问题,存储数据到磁盘就变成了存数据到数组,从磁盘取数据就是找到数组中的位置,对磁盘的管理也就成了对数组的管理
这样一个扇区的大小是512字节,接下来就是对扇区如何进行划分管理了
扇区中的块组
直接管理512字节还是过于麻烦,我们仍然需要对其进行设计才能很好的管理其中的内容
一个扇区会分成若干个这样的部分,其中块组相当重要
- inode Table保存的是文件的属性,每一个文件对应一共inode块,每一个inode块都有一个对应的编号,
- Block Bitmap是一个位图,表示特定的块组是否被使用
- inode Bitmap也是一共位图,表示特定的inode是否被使用
- Data Blocks用来存文件数据
- GDT是块组描述符,存了这个块组的信息,大小,已经使用多少,inode数量,还剩多少
- SuperBlock保存着文件系统的信息,每个块组都会备份,里面还存着对应块组的信息
因此我们想在磁盘中找到一个文件只需要找到inode的编号,找到对应的块组,找到inode,找到他的属性和内容
那么问题就变成了如何找到这个文件的inode编号,其实在文件的目录中就存放着文件名和对应文件的inode的关系,也就是说我们可以通过查表,用文件名找到inode编号
软硬链接
硬链接
我们刚刚说了,要找到一共文件的本质其实就是要找到他的inode
ln 源文件名称 链接名称
这个1、2其实就是硬链接个数,硬链接实际上就是给源文件起了个别名,类似于引用计数,他本身并没有实体,没有自己的inode
因此在删除文件的时候,不仅需要删除文件记录本身删除,还需要将硬链接数-1
软连接
ln -s
软连接是有实体的,有自己的inode,这个链接是指向原文件的,就相当于Windows的快捷方式,指的是原文件的路径
动静态库
- 静态库以.a结尾,程序在编译链接的时候就把库中的代码放到代码中
- 动态库以.so结尾,程序在运行时才链接动态库的代码,而动态库的
gcc/g++默认使用的是动态链接的方式,静态链接需要加上-static选项
因为动态库的内容可以在多个程序中共享,因此动态链接的程序占用空间更小
假如我们写了四个功能,分别是加减乘除,有对应的h文件和c文件
c语言形成可执行程序四个阶段是预处理、编译、汇编、链接
需要先使用指令将c文件汇编完成形成o文件,然后我们再使用别的指令进行链接
gcc -c add.c -o add.o gcc -c sub.c -o sub.o gcc -c mul.c -o mul.o gcc -c div.c -o div.o
然后就可以进行链接了
生成静态库
ar -rc libmycalcu.a add.o sub.o mul.o div.o
- ar是gnu的归档工具
- rc表示replace和create
- lib是库前缀,calcu是库名称,a是后缀,后面就是需要打包的文件了
使用静态库
gcc main.c -L. -lcalcu
-L用来指定目录,.表示当前目录,找不到会依次搜索环境变量指定的目录LIBRARY_PATH,系统指定的目录
-l指定库的名称
链接完成之后删掉静态库也能运行程序
生成动态库
gcc -shared add.o sub.o mul.o div.o -o libcalcu.so
也可以使用通配符
使用动态库
和静态库是一样的
gcc main.c -o main -L. -lcalcu