2、文件系统
- 命令 ls -l 查看文件信息:
[root@localhost linux]# ls -l 总用量 12 -rwxr-xr-x. 1 root root 7438 "9月 13 14:56" a.out -rw-r--r--. 1 root root 654 "9月 13 14:56" test.c
每行包含7列:模式;硬链接数;文件所有者;组;大小;最后修改时间 ;文件名
- 命令 stat 查看文件信息:
[root@localhost linux]# stat test.c File: "test.c" Size: 654 Blocks: 8 IO Block: 4096 普通文件 Device: 802h/2050d Inode: 263715 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2017-09-13 14:56:57.059012947 +0800 Modify: 2017-09-13 14:56:40.067012944 +0800 Change: 2017-09-13 14:56:40.069012948 +0800
注意:
Access最近访问文件时间(不会立即刷新,访问是一个比较频繁的行为,立即刷新则会减缓效率)
Modify:最近修改文件的时间(主要是文件的内容,立即更新)
Change:最近修改文件属性的时间(修改文件内容可能会造成文件属性的修改,立即更新)
如何读取文件信息:
通过读取存储在磁盘上的文件信息,然后显示出来
示图:
文件系统概念:
对于文件操作来说,我们操作的都是在内存打开的文件,而大多数文件都是未打开的文件并且储存在磁盘上,而对于磁盘上的文件OS也需要进行管理,由此就需要文件系统
示图:
确定磁盘的读写文件:
确定读写信息在磁盘的哪个盘面/柱面/扇区,但是这样的方式并不便于移植,由此我们将磁盘抽象成数组,数组的下标是单调递增不重复的数字,可以直接确定要读写的文件
分区管理:
磁盘分区就是使用分区编辑器在磁盘上划分几个逻辑部分,盘片一旦划分成数个分区,不同的目录与文件就可以存储进不同的分区,分区越多,就可以将文件的性质区分得越细,按照更为细分的性质,存储在不同的地方以管理文件
磁盘是典型的块设备,硬盘分区被划分为一个个block,一个block的大小是由格式化的时候确定的,并且不可以更改
如何进行管理:
示图:
说明:
Boot Block:该区域磁盘文件的驱动文件,如果驱动损坏,那么则无法进行读取对应区域的文件信息及数据
Block Group:ext2文件系统会根据分区的大小划分为数个Block Group,而每个Block Group都有着相同的结构组成
Super Block:存放文件系统本身的结构信息,记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
Group Descriptor Table:块组描述符,描述块组属性信息,整体group的空间使用信息,以及其他信息
Block Bitmap:Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
inode Bitmap: inode位图当中记录着每个inode是否空闲可用
inode Table:存放文件属性,即每个文件的inode,每个文件对应一个inode,而inode才是标识文件的唯一方式
Data Blocks:存放inode对应的文件数据
注:其他块组当中可能会存在冗余的Super Block,当某一Super Block被破坏后可以通过其他Super Block进行恢复;磁盘分区并格式化后,每个分区的inode个数就确定了
如何理解创建一个文件:
通过遍历inode位图的方式,找到一个空闲的inode,在inode表当中找到对应的inode,并将文件的属性信息填充进inode结构中,并将该文件的文件名和inode的映射关系添加到目录文件的数据块中,如果写入内容,需要通过Block Bitmap找到闲置的数据块,将数据写入数据块,并将映射关系写到inode结构中
如何理解对文件写入信息:
通过目录文件中的数据块找到文件名及其inode的映射,再找到对应的inode结构,再通过inode结构找到存储该文件内容的数据块,并将数据写入数据块;若不存在数据块或申请的数据块已被写满,则通过遍历块位图的方式找到一个空闲的块号,并在数据区当中找到对应的空闲块,再将数据写入数据块,最后还需要建立数据块和inode结构的对应关系
如何理解删除一个文件:
将该文件对应的inode在inode位图当中置为无效,将该文件申请过的数据块在块位图当中置为无效,并不真正将文件对应的信息删除,而只是将其inode号和数据块号置为了无效,所以当我们删除文件后短时间内是可以恢复的,如果再次创建文件及数据,可能将对应的数据块给覆盖,原来的数据也就没有了
如何理解目录:
目录也是文件,有自己的属性信息,目录的inode结构当中存储的就是目录的属性信息,比如目录的大小、目录的拥有者等;目录也有自己的内容,目录的数据块当中存储的就是该目录下的文件名以及对应文件的inode指针
注: 每个文件的文件名并没有存储在自己的inode结构当中,而是存储在该文件所处目录文件的文件内容当中。计算机只关注文件的inode号,只有用户才关注,用户需要看到文件名,所以将文件名和文件的inode指针存储在其目录文件的文件内容当中后,目录通过文件名和文件的inode指针即可将文件名和文件内容及其属性连接起来
3、软硬链接
软链接概念:
软链接又叫做符号链接,软链接文件相对于源文件来说是一个独立的文件,该文件有自己的inode号,但是该文件只包含了源文件的路径名,所以软链接文件的大小要比源文件小得多。软链接就类似于Windows操作系统当中的快捷方式
但是软链接文件只是其源文件的一个标记,当删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,但却不能执行或是查看软链接的内容了
命令ln -s 创建软连接:
硬链接概念:
硬链接文件就是源文件的一个别名,一个文件有几个文件名,该文件的硬链接数就是几
当硬链接的源文件被删除后,硬链接文件仍能正常执行,只是文件的链接数减少了一个
使用命令ln 创建硬连接:
注:硬链接文件的inode号与源文件的inode号是相同的,并且硬链接文件的大小与源文件的大小也是相同的,特别注意的是,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数都变成了2
为什么创建的目录的硬链接数是2:
创建一个普通文件,该普通文件的硬链接数是1,因为此时该文件只有一个文件名。而目录创建后,该目录下默认会有两个隐含文件.和…,它们分别代表当前目录和上级目录,因此这里创建的目录有两个名字,一个是dir另一个就是该目录下的.,所以刚创建的目录硬链接数是2
示图:
注:通过命令我们也可以看到dir和该目录下的.的inode号是一样的,也就可以说明它们代表的实际上是同一个文件
软硬链接的区别:
软链接是一个独立的文件,有独立的inode,而硬链接没有独立的inode
软链接相当于快捷方式,硬链接本质没有创建文件,只是建立了一个文件名和已有的inode的映射关系,并写入当前目录
六、动静态库
概念:
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间,缺点是一旦库缺失,所以依赖的程序都不可运行
静态库链接方式生成的可执行程序体积比较大,因为他会将库里面的代码拷贝至可执行程序,缺点是程序的体积比较大,浪费系统空间资源,但是如果库缺失不影响程序运行
示例:
注:编译时默认是动态编译,加上-static选项则是静态编译
库文件名称和引入库的名称:
如:libc.so -> c库,去掉前缀lib,去掉后缀.so,.a
1、制作使用静态库
注意:
制作静态库指令:ar -rc
ar是gnu归档工具;rc表示(replace and create)
查看静态库中的目录列表: ar -tv libmymath.a
t:列出静态库中的文件;v:verbose 详细信息
指定链接静态库:gcc main.c -L. -lmymath
-L 指定库路径;-l 指定库名
注:测试目标文件生成后,静态库删掉,程序照样可以运行
库搜索路径:
从左到右搜索-L指定的目录
由环境变量指定的目录 (LIBRARY_PATH)
由系统指定的目录(/usr/lib;/usr/local/lib)
2、制作使用动态库
示例:
注意:
生成动态库选项:
shared: 表示生成共享库格式;fPIC:产生位置无关码(position independent code)
动态库是文件,先从磁盘加载到内存上的共享区,并与进程的程序地址空间建立映射关系,由此映射的位置不能影响到进程就需要fPIC
编译选项:
-I:指定头文件搜索路径;-L:指定库文件搜索路径;-l:指明需要链接库文件路径下的哪一个库
运行动态库方法:
拷贝动态库.so文件到系统共享库路径下, 一般指/usr/lib
添加库路径到 LD_LIBRARY_PATH
ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
具体操作:首先将库文件所在目录的路径存入一个以.conf为后缀的文件当中;然后将该.conf文件拷贝到/etc/ld.so.conf.d/目录下;使用ldconfig命令将配置文件更新