文件描述符

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

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

可以看到执行的结果是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中都存储了具体如何进行文件操作。

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

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

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

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

文件流 ------ 硬盘

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

相关推荐
阿明69 分钟前
Linux进程【Linux】
linux·运维·服务器
Android系统攻城狮22 分钟前
Linux Gstreamer深度解析之gst_audio_resampler_update调用流程与实战(三十)
linux·运维·服务器·gstreamer音视频·音视频进阶
qetfw32 分钟前
Linux tcpdump 抓包实战:网卡、主机、端口过滤与 PCAP 分析
linux·tcpdump
pilifeng141 分钟前
Ubuntu Linux 目录结构详解
linux·ubuntu
电棍2331 小时前
ubuntu网卡失效
linux
律宏阔1 小时前
VMware 能识别 USB 设备,但无法连接(灰色)
linux
Rabitebla1 小时前
【Linux系统编程】指令(三):创建、删除、复制、移动、看内容
linux·数据结构·c++·算法
AR-26710-1 小时前
Linux Day9——复习第一部分(实操产出)
linux
天天喝旺仔3 小时前
Linux 性能排查实战:用 perf、strace 与火焰图定位 CPU、内存与 IO 瓶颈
linux·性能优化·运维开发
LuminousCPP3 小时前
Linux系统编程(二):从目录树到命令执行|路径、环境变量、alias 与文件操作入门
linux·经验分享·笔记