基础IO——文件描述符

news2024/10/7 20:30:29

文章目录

  • 1. 文件描述符fd
    • 1.1 open返回值
  • 2. 理解Linux下一切皆文件
  • 3. 文件描述符的分配规则
  • 4. 重定向的本质
    • 4.1 使用 dup2 系统调用
    • 4.2 追加重定向
    • 4.3 输入重定向

1. 文件描述符fd

1.1 open返回值

我们先来看下面的例子:
在这里插入图片描述
运行结果如下:
在这里插入图片描述
我们知道open的返回值小于0为失败,大于等于0为成功。

那么为什么从3开始,0,1,2是什么
原因是:0,1,2默认打开了。
0:标准输入,键盘
1:标准输出,显示器
2:标准错误,显示器

而在C语言中是:
在这里插入图片描述
它们是什么关系呢
首先,FILE是C库提供的结构体。结构体会封装许多成员,而对应文件操作而言,系统接口只认fd。所以,结构体里肯定有fd

证明0,1,2就是标准IO

我们先验证0标准输入:
在这里插入图片描述
运行结果如下:
在这里插入图片描述
然后验证1,2:
在这里插入图片描述
在这里插入图片描述

验证0,1,2和stdin,stdout,stderr的对应关系
在这里插入图片描述
因为stdin,stdout,stderr都是FILE类型的指针,可以用箭头来指向里面的数据。
在这里插入图片描述
可以看到它们就是0,1,2。

2. 理解Linux下一切皆文件

我们知道:一个进程是可以打开多个文件。进程 :打开文件=1:n。所以系统在运行中,可能会存在大量的被打开的文件,而OS肯定会管理这些被打开的文件。而管理就是先描述,再组织

先描述:一个文件被打开,在内核中,要创建被打开的文件的内核数据结构(struct file),里面包含了文件大部分内容和属性
在这里插入图片描述
再组织:对被打开的文件的管理,转化成为了对链表的增删查改

上面说过进程:打开文件=1:n的关系。那么进程如何和打开的文件建立映射关系呢
在这里插入图片描述
在struct task_struct中,有一个指向结构体的指针(struct files_struct *fs)
在这里插入图片描述
在struct files_struct 结构体中,有一个数组,这是一个指针数组,里面指向文件的结构体
在这里插入图片描述
这样我们可以根据下标来找到文件的内容
在这里插入图片描述

0,1,2对应的stdin,stdout,stderr是键盘,显示器,显示器。这些都是硬件,也是用struct file来标识对应的文件的吗

这就要理解Linux下一切皆文件了

第一个问题:如何如何用C语言来实现类呢
我们知道C语言的结构体里是不能写成员方法的,所以我们只能用函数指针。
在这里插入图片描述
如果我们想去调用的话,我们可以这样去传:
在这里插入图片描述
这样我们就可以面向对象的去使用了。

在这里插入图片描述
这是我们的外设设备,每一个外设都有属于自己的读,写方法。
在这里插入图片描述
不同的设备,对应的读写方法一定是不一样的

然后如何去调用这些方法,就和我们上面说的一样。
在这里插入图片描述
所以,当我们想访问某个设备时,操作系统就会创建一个struct file。而在上一层,就是我们刚刚说的进程和struct file的关系了。

3. 文件描述符的分配规则

前面的例子中:默认打开的是3,因为0,1,2已经打开了。

文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符

我们再来看下面的例子:
在这里插入图片描述
我们先把0关闭了。看一下运行结果:
在这里插入图片描述
我们再换成2:
在这里插入图片描述
运行结果:
在这里插入图片描述
我们再换成1:
在这里插入图片描述
运行结果:
在这里插入图片描述
但是1,它什么都不打印了。这是为什么呢?按照文件描述符的分配规则,fd的值一定是1啊。
原因是:一开始我们把1关上了,然后我们open了log.txt文件,那么1就不在指向对应的显示器了。而是已经指向了log.txt的底层struct file对象了

在这里插入图片描述
但是你会发现,log.txt里还是没有。因为我们需要刷新缓冲区。
在这里插入图片描述
在这里插入图片描述
这里,我们要说两个问题:一个是重定向的本质,一个是缓冲区的问题。

4. 重定向的本质

我们先看下面的代码:
在这里插入图片描述
这个把printf换成fprintf,好理解。那么本来应该要往显示器打印,最终却变成了向指定文件打印,这个不就是重定向吗?

正常的情况:
在这里插入图片描述
当我们把1关闭了,然后再打开文件的情况:
在这里插入图片描述
而在C标准库中,stdout里的fd我们天然的设成了1。但是它并不知道1的file对象已经发生了变化,所以还是向1的对象里写入。所以就会写入到新文件里了。

重定向的原理:如果要进行重定向,上层只认0,1,2,3,4…这样的fd,我们可以在操作系统内部,通过一定的方式调整数组的特定下标的内容(指向),我们就可以完成重定向操作了

4.1 使用 dup2 系统调用

在这里插入图片描述
这是一个普通的文件打开操作。如果此时我们要输出重定向到文件里,一定是让3里的file* 的内容复制给1里的file* 。
在这里插入图片描述
所以,最后都和fd里的内容一样了

上面的一堆数据,都是内核数据结构,只有操作系统有权限。所以,操作系统必定会提供接口。那么这个接口就是dup2。
在这里插入图片描述
这个函数的意思是:
在这里插入图片描述
将oldfd复制给newfd, 两个文件描述符指向同一个文件
注意:这里复制的不是下标,而是下标里所指向的内容

所以,根据上面所说的过程,这个函数的参数我们该如何传呢?
答案就是:dup2(fd,1)

在这里插入图片描述
在这里插入图片描述
这样就完成了重定向。

dup2也是有返回值的,但是不常用:返回值: 若dup2调用成功则返回新的文件描述符,出错则返回-1
在这里插入图片描述
这就是当我们输出重定向完成了,如果我们不想要fd,可以把它关了。
在这里插入图片描述
这样,还是可以在1里完成重定向。

4.2 追加重定向

追加重定向,只需改一下标记位就行了:
在这里插入图片描述
运行结果如下:
在这里插入图片描述

4.3 输入重定向

在这里插入图片描述
这是正常的从键盘输入,显示器打印的方式。
在这里插入图片描述
如果我们想输入重定向,那么就不是从键盘读,而是从文件里读。
在这里插入图片描述
我们将0(stdin)重定向。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/101724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

磺基-CY5 马来酰亚胺 Cyanine5 Maleimide

磺基-CY5 马来酰亚胺 Cyanine5 Maleimide Cyanine5 maleimide是单一活性染料,有选择性的与硫醇基团(比如蛋白和多肽的半胱氨酸)结合以进行标记。我们使用水溶的Sulfo-Cyanine5 maleimide标记抗体和其他敏感蛋白。Cyanine5是Cy5的类似物&am…

Pb协议的接口测试

Protocol Buffers 是谷歌开源的序列化与反序列化框架。它与语言无关、平台无关、具有可扩展的机制。用于序列化结构化数据,此工具对标 XML ,支持自动编码,解码。比 XML 性能好,且数据易于解析。更多有关工具的介绍可参考官网。 P…

Java8新特性学习

文章目录Lambda表达式为什么使用Lambda表达式Lambda表达式语法语法格式一:无参数,无返回值语法格式二:有一个参数,并且无返回值语法格式三:若只有一个参数,小括号可以省略不写语法格式四:有两个…

Docker容器数据卷

是什么 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:卷的设计目的就是数据的持久化,完全独立…

LSTM(Long Short-Term Memory)

长短期记忆(long short-term memory,LSTM),LSTM 中引入了3个门,即输入门(input gate)、遗忘门(forget gate)和输出门(output gate),以…

华为时习知,让企业培训更简单!

在数字经济的发展过程中,人才始终是不容忽视的关键因素,企业对数字化人才培养的需求也愈加迫切。然而企业培训说起来简单,要做好却绝非易事。企业可能会面临员工分散各地、流动性大、关键岗位人才培训等复杂培训场景问题,无法高效…

为什么我们说NFT拥有无限潜力?

欢迎来到Hubbleverse 🌍 关注我们 关注宇宙新鲜事 📌 预计阅读时长:8分钟 本文仅代表作者个人观点,不代表平台意见,不构成投资建议。 2021年底,NFT就已经发展得炙手可热了,热门到410亿美元投…

YOLO-V5 算法和代码解析系列(一)—— 快速开始

文章目录运行环境配置Demo重新训练 YOLO-V5s运行环境配置 环境配置的官方教程如下,如果一些库安装失败,导致安装中断,可以单独安装一些库,比如 Pytorch,然后再执行下列安装步骤,具体如下: 个人建…

国内食糖行业数据浅析

大家好,这里是小安说网控。 食糖行业是国民消费不可或缺的产业之一。2022年9月份国内成品糖产量当期值为40.4万吨,同比增长30.7%;10月份当期值为63.7万吨,同比下滑2%。今年1-10月份,国内成品糖产量累计值为1089.4万吨&…

艾美捷细胞糖酵解分析试剂盒基本参数和相关研究

艾美捷基于糖酵解细胞的测定试剂盒提供了一种比色法,用于检测培养细胞产生和分泌的糖酵解最终产物L-乳酸。在该测定中,乳酸脱氢酶催化NAD和乳酸之间的反应,产生丙酮酸和NADH。NADH直接将四氮唑盐(INT)还原为吸收490至5…

【High 翻天】Higer-order Networks with Battiston Federico (3)

目录模型(1)Equilibrium modelsBipartite modelsMotifs modelsStochastic set modelsHypergraphs modelsSimplicial complexes models模型的目的是再现、解释和预测系统的结构,最好用涉及系统两个或多个元素的交互来描述。为了考虑其输出的可…

【1971. 寻找图中是否存在路径】

来源:力扣(LeetCode) 描述: 有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] [ui, vi] …

计算机毕设Python+Vue学衡国学堂围棋社管理系统(程序+LW+部署)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

nvidia 使用

watch -n 0.5 nvidia-smi ./build/examples/openpose/openpose.bin --video examples/media/video.avi Linux CPU&GPU烤机(压力测试) 盛夏捷关注IP属地: 青海 0.1342021.04.14 09:50:16字数 152阅读 6,307 GPU-burn工具进行GPU烤机 下载Multi-G…

基于MATLAB的车牌识别系统设计(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

vue之非父子组件通信实现方式

在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信。这里主要讲两种方式: Provide/InjectMitt全局事件总线 1、Provide和Inject 应用场景 比如有一些深度嵌套的组件,子组件想要…

SVG 在前端的7种使用方法,你还知道哪几种?

本文简介 点赞 关注 收藏 学会了 技术一直在演变,在网页中使用 SVG 的方法也层出不穷。每个时期都有对应的最优解。 所以我打算把我知道的 7种 SVG 的使用方法列举出来,有备无患~ 如果你还知道其他方法,可以在评论区补充~ 1. 在浏览器直…

PMO(项目管理办公室)的未来趋势

PMO(项目管理办公室)是在组织内部将实践、过程、运作形式化和标准化的部门,也是提高组织管理成熟度的核心部门。现在,让我们把目光投向当前PMO的典型职责之外,思考一下:PMO的未来是什么? 如今&a…

Java:进一步理解多态性

Java:进一步理解多态性 每博一文案 有人说我心里有事,但我谁也不想说,沉默不是没有情绪,而是我明白了,说了又没有意义, 比起诉说的委屈和不甘,沉默或许更好。当我们经历越多真实与虚假&#xf…

Docker安装(centos 7)

安装 以在centos安装为例,主要有以下几个步骤 1、确定你是CentOS7及以上版本 2、卸载旧版本 3、yum安装gcc相关 yum -y install gccyum -y install gcc-c 4、安装需要的软件包 执行如下命令 yum -y install gcc-c 5、设置stable镜像仓库 由于docker外网镜像…