文件描述符

上篇博客中讲到,系统调用接口中找到指定文件的方式是通过文件按描述符,那什么是文件描述符?

我们通过下面的程序来看看:

可以看到执行的结果是3,不难想到,管理流的结构是类似于数组的。3下标代表第4个流,那前三个流是什么?

标准输入流 ------0,键盘

标准输出流------1,显示器

标准错误流 ------2,显示器

这些是系统默认帮我们打开的,这就是我们后续打开的文件的文件描符都是按照3,4,5,...这样的顺序来的。

那不妨推测一下,这个数组存储的内容是什么?

Linux中存在一个结构体,专门来管理文件信息,files_struct

前面讲过close接口,如果close(1) 会发生什么?在这基础上添加一个新流会发生什么?

说明了,如果你把标准输出流删除了,再使用printf的话就不会向屏幕输出。

从上面看到,files_struct 中的 fd_arr 存储下标的从0 - n,哪个没有了,就放在哪个下标。

而printf是输出到fd_arr中下标为1的流中。

那假设现在我想修改fd_arr中某个流的下标,比如我想把标准错误流(下标为2) 和标准输出流换位置怎么办。

先用dup备份一下,再用dup2进行覆盖,dup2(int oldfd,int newefd) 这里是第一个参数覆盖第二个参数的流,比如dup2( 2,1) 那么下标为1的流就会被覆盖成下标为2的流,同时你可以把下标为2的哪个备份给close,如果你觉得有必要的话!

重定向:

很早的时候我们就讲过重定向的使用:

重定向分为 > 和 >>

>:相当于在open中flag或上了O_TRUNC,这个在每次写入之前都会清除文件内容

>>:相当于在open中flag没有或上O_TRUNC,这个是追加写入,在上次的基础上写入

重定向的本质(下面以 > 为例):

ls > 目标处,这个实际上就是 先把这个目标添加到fd_arr中,再dup(目标的fd,1),就是将这个覆盖标准输出流,是这个目标成为输入的对象文件!

所以这个写法的格式是:

commad newfd>oldfd ------对单个流进行重定向,相当于执行了 dup2(oldfd,newfd)

command newfd>oldfd1 oldfd1>oldfd2 这个操作就相当于把newfd 弄成oldfd2 ,这里举这个操作目的是想说明可以多次重定向,格式是 command newfd1>oldfd1 newfd1>oldfd2 ......

上面的操作可以转换成其他形式

command newfd1>oldfd newfd2>&newfd1 这个操作相当于dup2(oldfd,newfd1) dup(oldfd,newfd2)

这里&newfd1的意思是下标为newfd1指向的流!

流的刷新

全缓冲:

刷新条件:

只有当缓存区满了,才会刷新到内存中

行缓冲:

刷新条件:

遇到 '\n' 就刷新一次

无缓冲

刷新条件:

一旦数据到缓存区中,就直接刷新到内存中

手动刷新 flush(int fd)

这个的具体操作不妨留到下一篇博客 缓存区 中进行详细讲解

现在重新审视一下系统调用,显示通过open,在files_struct中存储这个file,并返回下标,接着我们通过这个下标来寻址file,接着进行wirte等操作。

那这些文件操作又是如何执行的?

很容易观察的一点,往屏幕上write和往文件中write的操作不相同,那这个不就说明了根据不同的file流,文件操作也不相同!!!

那系统如何知道要执行哪一种操作?

根据file中的人不同,此时我们就要了解一下file的内容了

file结构体中又存在一个结构体 file_operation* f_op;从类型中就可以读出这个是具体的文件操作的指针

这里面几乎都是函数指针!所以我们就得出了一个结论,每个file中都存储了具体如何进行文件操作。

往深处想一想流和硬件是有强相关的

标准输入流 ------键盘

标准输出流 ------屏幕

标准错误流 ------屏幕

文件流 ------ 硬盘

所以这里就把我们对硬件的操作转换成了对文件的操作!这就是一切皆文件在硬件上的理解

相关推荐
·薯条大王5 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
小小、码农8 小时前
Linux进程控制:从fork到exec,手写一个简易Shell
linux·运维·服务器
不会就选b9 小时前
Linux之进程间通信(二)---模拟进程池
linux·运维·服务器
沫璃染墨11 小时前
《从零入门Linux系统篇(十五):系统工具篇·六——GDB调试器详解:从程序执行控制到高级调试技巧》
linux·运维·服务器·c语言·c++
AIgorithmGEEK11 小时前
Linux 环境变量完全指南:从入门到理解底层原理
linux·运维·服务器
酷可达拉斯12 小时前
Linux操作系统-升级OpenSSH修复漏洞
linux·运维·服务器·云计算
Molesidy13 小时前
【Linux】基于busybox的根文件系统的完善
linux·服务器·嵌入式linux
jufeng130716 小时前
【系列:MiniKV 原理剖析 · 第 6 篇】
linux·软件工程·个人开发·makefile
IT摆渡者16 小时前
ubuntu系统网络问题
linux·运维·ubuntu
jufeng130716 小时前
【系列:MiniKV 原理剖析 · 第 5 篇】
linux·网络·c++·软件工程