这里写目录标题
- 文件存储理论补充
- dentry、inode
- 文件其他操作
- stat函数
- 作用
- 函数原型
- 代码(以获取文件大小为例)
- 补充(获取文件类型)
- lstat函数
- 作用
- 函数原型
- 代码
- 补充(获取文件权限)
- 总结
- tips
- link函数
- 作用
- 简介
- 函数原型
- 一级目录
- 二级目录
- 二级目录
- 二级目录
- 一级目录
- 二级目录
- 二级目录
- 二级目录
- 一级目录
- 二级目录
- 二级目录
- 二级目录
文件存储理论补充
dentry、inode
首先我们知道,inode,在创建硬链接的时候用到过,如下图:
当我们创建一个文件的硬链接时,该硬链接会有一个与文件一样的Inode
但是Indoe是什么:
Inode是一个结构体,存储着文件属性的结构体,他会存储一个文件的各种属性,以及“该文件在磁盘中的位置”,但是没有存储文件名
而dentry,存储着文件名+该文件的inode,相当于是一个目录,其名字也是"目录项"
当我们描述一个文件时,首先会根据dentry,找到他的inode,之后就知道了该文件的各种属性,而通过inode记录的文件的磁盘位置,就可以看到文件的内容了
而我们平时创建硬链接的底层原理是:
创建一个硬链接,就会创建出一个dentry,其文件名就是硬链接的文件名,匹配的就是目标文件的inode,这样就建立了硬链接,这也是为什么硬链接会与原文件有相同的inode
而删除硬链接,以及删除文件:
删除硬链接,其实就是删除dentry,删除一个dentry,其硬链接计数就会减一
当删除完所有的硬链接,然后又删除了文件,那么就会把所有的dentry都删除了,那么这个文件的inode就没有dentry引用了
但是此时,在磁盘中的文件安然无恙,也就是说,删除文件并不会真正的去磁盘中删除文件,而这个磁盘的内容,只有在没有dentry引用其inode的情况下,会被其他文件所覆盖,覆盖了才是真正意义的删除
数据恢复:
如果磁盘文件内容还没有被覆盖,我们就可以对该部分数据再次建立一个inode以及dentry,就可以做到对数据的恢复
文件其他操作
stat函数
man 2卷
作用
获取文件的各种属性
函数原型
参数一:文件路径(精确到文件名)
参数二:传出参数,指向struct stat类型的变量的指针
其中 stat结构体的内容:(实际上就是inode的内容,也就是我们平时ls -l (小L)显示的内容)
代码(以获取文件大小为例)
最终在sbuf结构体中已经有了该文件的所有属性,想打印哪个就打印哪个
这里我们打印文件的大小,这个可以实现与“lseek获取文件大小”相同的效果,且该方式是推荐的方法
注意使用%ld进行打印,其类型为unsinged long int
补充(获取文件类型)
拿到stat结构体变量中的数据后,在该结构体中有一个st_mode属性,利用该属性,配合其提供的宏函数,我们可以完成上图中的一些判断(如判断该文件是否是一个普通文件、还是一个目录?…)
而宏函数一般只返回0或1,也就是返回真或者假,他会告诉你是或不是
代码:
但是:
当我们测试其他类型没有问题,但当我们测试“符号链接”类型时,出现了问题:
首先我们创建两个符号链接:
结果是:
可以看到,最终打印的都是符号链接所指向的最终的实体文件,该现象称为stat穿透,默认情况下stat是穿透的,如何解决,看下一个函数
lstat函数
作用
解决stat函数的“穿透”现象
函数原型
与stat函数原型一样
代码
与stat函数使用规则一样,只不过加了一个 “l” (小L)
结果:
实际上,我们的vim、cat,都是穿透的(作用到最终指向的实体文件)
而ls -l 是不穿透的 (作用于“链接本身”)
补充(获取文件权限)
在man中的demo没有使用宏函数进行文件类型的判断,而是使用了位运算
简单解释一下:
这里还是用到了位图:
一个位图,有2字节,16位,从右向左,每三个为一组,一共三组,共9位,分别代表不同组的文件权限(用户、用户组、其他用户)
再往左三位是特殊权限位
最开始的四位是文件类型,四位,转为八进制其总数就是17(即017,0是八进制的前缀)
上图中的S_IFMI就是017,也就是其二进制为1111 000 000 000 000,由于他前面都是1,所以可以作为掩码使用,所以st_mode & S_IFMT,最终得到S_IFMT下面的宏,就对应其表示的信息,由此可见,使用该方式,不仅可以获取到文件类型(宏函数可以获取),还可以获取到不同组的执行权限等信息(宏函数获取不到):
总结
因为lstat与stat没有其他区别,而且lstat不会进行穿透,所以,以后我们直接使用lstat就可以了
tips
在一些重要的函数的man手册中,我们点击“G”,会跳到最下面,这里可能会有一个当前函数的demo示例
link函数
man 2卷
作用
我们之前创建硬链接,都是通过命令行的ln命令,但是在代码中,我们不可能去到终端敲命令,所以就有了link函数,他就是负责创建硬链接的,实际上,是为文件新建一个dentry项
简介
建立硬链接,也就是新建dentry项,而使用mv命令修改文件名时,也是修改了dentry,并不对真正的文件做操作