目录
一、Linux 文件系统中的 inode
二、软硬链接
三、动静态库
在 Linux 系统中,文件系统和动静态库是非常重要的概念。本文将带大家深入了解这些内容,让你在技术之路上更进一步。
一、Linux 文件系统中的 inode
何为文件系统?对计算机中打开和关闭的文件做管理,打开的文件如何管理?之前的文章中讲到了,通过加载到内存,用struct file描述打开的文件; 那没有打开的文件呢?存在磁盘,如何管理,通过inode管理!
inode 是 Linux 文件系统中的一个关键概念。它是文件系统用于索引和管理文件的基本数据结构。每个文件和目录都有一个与之对应的 inode。inode 记录了文件的属性,如文件类型、权限、所有者、大小等,以及文件数据在磁盘上的存储位置。理解 inode 对于理解文件系统的运作至关重要。
查看文件的inode编号:
ls -li
可以看到,第一列的数字就是inode编号
对于单个文件想查看更详细的信息:
stat 文件名
其中文件最重要的属性:inode
如何理解inode?
首先,对于磁盘上的文件如何管理,当然是对磁盘管理了,磁盘如何管理呢?容量太大了,我们分区管理,每个区再分成一个个块组(block group),根据分治的思想,管理好了一个个块组,就管理好了一整个分区,进而管理好了一整个磁盘!
而inode就是块组中很重要的一个概念,每个块组中,都有一个inode Table,其中每一个inode可以看作一个结构体,并给他们编号(返回给上层),结构体内的字段就是文件的属性,当创建一个文件时,就会填充这些结构体字段。
- Block Group:文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相 同的结构组成。
- 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量, 未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的 时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个 文件系统结构就被破坏了;Super Block是区级的数据,它会随机分配到几个块组中,当Super Block被破坏时,就会找到备份的来恢复数据。
- GDT,Group Descriptor Table:块组描述符,描述块组属性信息,一个块组有一份GDT来描述、管理、记录它本身
- 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没 有被占用
- inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。 i节点表:存放文件属性 如 文件大小,所有者,最近修改时间等 数据区:存放文件内容
二、软硬链接
- 硬链接:硬链接是指多个文件名指向同一个 inode。它就像是文件的多个别名,删除其中一个文件名并不会影响文件本身。
- 软链接:软链接则是一种特殊的文件,它指向另一个文件或目录。软链接可以跨越文件系统,删除源文件会导致软链接失效。
创建硬链接的指令:
ln 被链接的文件 硬链接名
硬链接不是一个独立的文件,创建一个硬链接就相当于在当前目录中增加一条文件名到inode的映射信息,且inode对应文件的硬链接数+1;一个文件的硬链接数为0时,这个文件才真正被删除(用户级);
硬链接的应用:路径切换系统的构建,每个文件夹中的 . 和 .. 都是硬链接,来构建出文件路径的切换,但是,这件事上Linux只许州官放火,不许百姓点灯,linux是不允许用户对目录创建硬链接的,这是为了防止文件路径成环
创建软链接:
ln -s 被链接的文件 软链接名
软链接很类似于Windows中的快捷方式,但是它不同于硬链接,它是一个独立的文件,有属于自己的inode,它的文件内容其实就是:目标文件的文件路径;这样就可以通过打开软链接达到和打开目标文件一样的效果
链接的删除:
可以用rm
但也有专属删除链接的指令:unlink
三、动静态库
- 动态库:动态库在程序运行时被动态加载,可以实现代码的共享和复用。它具有灵活性高的优点,但也可能带来一些运行时的复杂性。
- 静态库:程序在编译链接的时候把库的代码直接拷贝到可执行文件中。程序运行的时候将不再需要静态库
linux中
动态库:.so
静态库:.a
Windows中:
动态库:.dll
静态库:.lib
其实无论是动态库还是静态库,都是把一堆源文件编译处理出的.o文件(二进制文件)整理在一起,在加上这些源文件对应的头文件,就是一个完整的库了,这样既隐藏了库的源代码,也能让其他开发者使用这个库的功能
静态库的生成:
gcc -c xxx.c
ar -rc lib.a xxx.o xx.o
先通过gcc的-c选项生成二进制文件,再把所有的二进制文件通过ar命令生成.a文件
得到静态库后,生成可执行程序时把库链接到可执行程序上即可(实际就是拷贝库)
gcc Main.c -I 库的头文件路径 -l 库名 -L 库文件的路径
动态库的生成:
gcc -fPIC -c xxx.c
gcc -shared -o lib.so xxx.o xx.o
-fPIC选项是为了生成位置无关码
得到了动态库,那么怎么使用呢?
它可不像静态库那样生成可执行程序时直接把库的内容
gcc Main.c -I 库的头文件路径 -l 库名 -L 库文件的路径
此时生成a.out,但是运行时根本不可以运行,需要注意的是,我们使用-I
,-L
,-l
这三个选项都是在编译期间告诉编译器我们使用的头文件和库文件在哪里以及是谁,但是当生成的可执行程序生成后就与编译器没有关系了,此后该可执行程序运行起来后,操作系统找不到该可执行程序所依赖的动态库,可以使用lld指令查看可执行程序依赖哪些动态库
lld a.out
执行程序所依赖的动态库没有被找到时,有四种处理方法:
- 拷贝库文件到系统共享路径下(如centOS的是: /lib64/ )
- 更改环境变量: LD_LIBRARY_PATH
- 配置/etc/ld.so.conf.d/,
我们可以通过配置/etc/ld.so.conf.d/的方式解决该问题,/etc/ld.so.conf.d/路径下存放的全部都是以.conf为后缀的配置文件,而这些配置文件当中存放的都是路径,系统会自动在/etc/ld.so.conf.d/路径下找所有配置文件里面的路径,之后就会在每个路径下查找你所需要的库。我们若是将自己库文件的路径也放到该路径下,那么当可执行程序运行时,系统就能够找到我们的库文件了(需要使用
ldconfig
命令将配置文件更新一下)- 在系统共享路径下,生成库文件的软链接(保存库文件的绝对路径)