目录
缓冲区
缓冲区执行概念
C语言缓冲区存在于FILE结构体中
用户缓冲区刷新到OS缓冲区的策略
发生重定向
redir未重定向。
redir重定向。
磁盘的存储原理
细讲:
Inode table
Date block
Inode bitmap
Block bitmap
Group Descriptor Table
super Block
在目录下运行cat程序
软硬链接
软硬链接画图理解
编辑
相关知识点:
缓冲区
缓冲区执行概念
在系统文件写入时,在用户层与系统层,都存在着缓冲区,而系统层对文件写入是加载到系统缓冲区,然后在写入到磁盘文件中,然而用户层则是通过写入数据先放到用户缓存中,然后再通过系统调用接口,将用户缓冲区数据加载到系统缓冲区(通过fd甄别)
C语言缓冲区存在于FILE结构体中
所以我们在printf、fprintf、fputs等等都是写入到用户缓冲区中
用户缓冲区刷新到OS缓冲区的策略
用户->OS刷新策略
1、立刻刷新:使用fflush(FILE*)
2、行刷新(行缓冲\n):显示器打印
3、缓存区满了,才刷新(全缓冲):向磁盘文件写入数据;(函数结束一次性打印:fclose->fflush+close()抽象的认为);
发生重定向
当原本打印在显示器的字符串打印到文件中会发生
显示器->文件
行缓冲->全缓冲
int main()
{
//close(1);
const char*mgs1="==标准输入==\n";
write(1,mgs1,strlen(mgs1));
const char*mgs2="==标准错误==\n";
write(2,mgs2,strlen(mgs2));
printf("hello world\n"); 18
fprintf(stdout,"wdsj\n");
close(1);
return 0;
}
运行代码
让我们重定向写入log.txt
我们的printf于fprintf的写入失效了,既没有在显示器中也没有再文件中,什么情况呢?
由于重定向到文件中原本打印策略是行缓冲,然后改变为了全缓冲打印文件中。
我们printf与fpantf打印的数据不在打印再显示器中,而是加载到用户缓冲区中
然后我们提前关闭了文件log.txt(bash的重定向将stdout改变为向log.txt写入)
导致了fd=1中的文件缓冲无法加载到OS文件缓冲区中 再进程结束刷新用户缓冲区的时候就,进程就无法刷新用户缓冲区的数据到文件内核缓冲区了,然后再写入文件。
注意,一个FILE指针一个缓冲区,缓冲区不共用。
但是为什么write写入到文件中了呢?不是文件fd关闭了吗?因为wirte是系统函数,他可以直接写入到文件内核缓冲区,不用经过用户缓冲区,所以当我们提前关闭fd=1不影响再内核缓冲区的数据。
在进程结束的时候(main的return 或者exit()),刷新用户缓冲区与OS缓冲区,fd关闭了影响到用户缓冲区刷新数据到内核缓冲区,但是不影响内核数据刷新到磁盘中。
redir未重定向。
打印到显示器上,显示器使用的是行缓冲原理,在遇见\n就会立刻从用户缓冲区刷新到文件缓冲区中,数据打印在显示器上。所以关闭fd:1,该进程不受影响。
而如果提前关闭fd:1
无法通过fd:1下标对应的地址访问对应的显示器struct file文件结构体。
但是不影响fd:2访问显示器文件结构体!!
redir重定向。
写入到系统缓冲区的字符串会,会立刻写到磁盘中,不管是否由刷新直接写入
这是我实验出来的,如果由错误请大佬留下你的宝贵意见。
全缓冲:C语言函数:printf,fprintf的流的数据被保存在用户缓冲区中,无论有没有'\n'都将停留在用户缓冲区中,等待主动刷新或者程序正常结束刷新缓冲区到文件缓冲区中。
但是write系统接口,不需要加载到用户缓冲区,直接加载到相应文件缓冲区中,当前写入结束直接写入到磁盘中。
运行代码
最后关闭fd:1不影响系统接口write,说明在关闭前系统接口就将数据写入到file中,而C语言接口未写入到任何地方,验证了C语言有缓冲区,在重定向后“\n”将无法主动刷新数据到文件缓冲区,而在我们关闭了进程fd:1的文件描述符,进程在结束以后将无法根据fd:1刷新数据到对应的文件中。
磁盘的存储原理
我们将磁盘想象成一个超级大的数组
将数组的每个区域划分,放大3区查看详细内容
boot block : 该区域的初始阶段,表示着加入3区的开始,直到下一个boot block的出现,这段空间都为3区域的的内容。我们管理好3区域就可以类似复制的类型,管理好其他区域.
对3区域继续划分,划分n个block groud区,放大视角观察block groud 0;
super block:包含所有block块信息,同区域的块信息相同(block ground 0~n,super block相同);
Group Descriptor Table:保存着当前块群的使用情况信息
block bitmap : 保存当前群块的使用与未使用的Date block 位置,使用二进制标识,0标识未使用,1标识已使用。
Inode bitmap :保存当前未被使用与已被使用的Inode table信息位置,与block bitmap 相同,也是二进制标识使用与未使用。
Inode table : 里面保存的是一个一个结构体一样的数据.它存储的是该文件的属性信息如:文件权限,文件大小,文件日期,还保存对应的Date block 的地址信息。
Date block:里面保存的是一个一个结构体一样的数据.它存储的是该文件的内容如:C源文件写的代码,图片的信息等待
细讲:
Inode table
也类似一个大大的数组(也可能是链表,不影响概念理解)存放结构体数据,像一个桌面,放着多个盒子(结构体数据),里面存储着文件的属性(每个盒子有着自己唯一的Inode编号,这里的唯一范围包括整个磁盘的Inode table数据)
Date block
也类似一个大大的数组(也可能是链表,不影响概念理解)存放结构体数据,也像一个桌面,放着多个盒子(结构体数据),里面存储着文件的内容,根据Inode保存的date block地址找到的对应的数据盒子,可能在Inode盒子结构体中存在数组成员存储多个Date block 数据,也可能结构体有个指针指向这头Date block其他的Date block链式存储方式链接,我们不深究.
Inode bitmap
类似于花名册,查看Inode Table的已使用空间与未使用空间的分布情况。利用二进制的0和1
0表示该位置未使用,1表示已使用。
Block bitmap
也是和Inode bitmap一样花名册。
Group Descriptor Table
保存信息位当前Group区块Date block与Inode Table使用情况以及其他数据。
super Block
来存储基本的文件系统类别数据。保存整个当前boot block中所有Block group 的使用情况。每个Block group都有一份,虽然冗余但是如果其他Block group出错,可以根据同区域的其他block找到该区域相关情况。
inode:类似于每个文件都有一个inode编号,类似人的身份证
在磁盘中每个文件都有唯一的Inode。这是改变不了的。
在目录下运行cat程序
首先我们知道,我们所有创建的文件或目录文件都是在一个目录下创建的。目录存储的数据其实就是该目录中文件与其Inode对应关系。
好了脑子里存着这个概念
这段代码运行的逻辑是什么呢?(cat文件的运行我们不聊)首先在根据当前目录(.)的Inode值-->目录的Inode结构体->目录的Date group->在Date group下找到proc.cc文件名对应的Inode-->然后根据proc.cc的Inode值找到对应的Inode结构体-->根据Inode结构体找到Date group中存放的数据-->通过cat打印在显示屏文件中。
软硬链接
有了上面的基础逻辑,让我们看看什么是软硬链接
让我们对该可执行文件构建软链接
当我们执行rlink也可以执行该程序
再让我们对该可执行文件构建硬链接
headlink也可以运行该代码,那么区别是什么呢?
执行指令ls -i -l
会发现headlink与test的Inode是一样的,而rlink的Inode与rlink的代码是不一样的。
因为前面说过一个Inode代表一个文件的编号,所以软链接其实就是生成一个文件,而硬链接则是,给文件起别名,类似于语言级别的引用。
当我们删除可执行文件
硬链接依旧可以执行程序,而软链接无法再去执行程序了。这是为什么呢?让我们画图理解以下
再一个目录下硬链接的文件名与test用同Inode,而软链接与可执行程序有着不同的Inode。
软硬链接画图理解
所以软链接其实是在目录中创建新文件内容保存着可执行程序的相对路径,而硬链接就是再该目录下多了一个文件名字,但是与可执行程序有着同Inode,访问的文件其实是一样的。
当我们删除test
其实就是 删除该文件下的test文件名字与其对应Inode,但是headlink还链接着该Inode所以Inode bitmap不会置0 对应的block bitmap也不会置0,所以运行硬链接依旧可以执行程序。但软链接是通过该可执行文件名来运行程序的,一旦删除文件名字,软软件将失去链接关系!!!
所以:软链接文件只保存链接文件对应目录下的文件名,不报错文件Inode
: 硬链接文件就是他的一份Inode文件名拷贝,名字不同但是Inode相同。
相关知识点:
软链接:
- 1.软链接,以路径的形式存在。类似于Windows操作系统中的快捷方式
- 2.软链接可以 跨文件系统 ,硬链接不可以
- 3.软链接可以对一个不存在的文件名进行链接
- 4.软链接可以对目录进行链接
硬链接:
- 1.硬链接,以文件副本的形式存在。但不占用实际空间。
- 2.不允许给目录创建硬链接
- 3.硬链接只有在同一个文件系统中才能创建