Linux - fd文件描述符和文件详解

news2024/11/26 17:32:11

                                        ​​​​​​​        ​​​​​​​             ​​​​​​​ 

                                               感谢各位 点赞 收藏 评论 三连支持

                                              本文章收录于专栏【Linux系统编程】   

                                                     ❀希望能对大家有所帮助❀

                                                       本文章由 风君子吖 原创

        ​​​​​​​        ​​​​​​​        ​​​​​​​               

前言

之前我们学习回顾了C语言文件操作的接口函数,并且学会了使用系统给我们提供的文件操作接口函数,

还知道了许多的概念,对于语言层面上的接口函数,它们在底层必然会对系统接口函数进行封装,这不仅便于我们使用,而且还实现了语言的跨平台性。

而学习系统调用接口,就是学习语言层面上我们一些我们无法理解的东西,能够更好的了解底层,再今后的学习更加受益匪浅!

而在Linux中,万物皆文件,所以不仅仅只是磁盘上存储的文件叫文件,我们的各种硬件也能被称之为文件,所以,我们调用系统提供的文件操作函数也可以对硬件进行各种操作,当然,这种操作并不是我们用户层来操作的,而是进程经过OS之手来进行操作的,因为只有操作系统才有对硬件进行IO的权限!

上一篇文章,我们对于文件描述符fd进行了初步的了解,而今天,我们就来详细讲解文件描述符fd与整个文件体系的密切关系

文件描述符fd

想要理解文件描述符就得明白这样一个概念,怎么样的文件才会被给予文件描述符? 一台计算机中的磁盘上可能会有上万的文件,那么我们需要对所有的文件都进行管理吗? 肯定不能,所以,我们只能对被进程打开的文件进行管理,而这些文件也会被加载到内存中,而这些被打开的文件,就会被给予文件描述符。

上篇文章中,我们从打印的文件描述符来看,它似乎是一串连续的数字,并且我们打开的文件的描述符都是从3开始依次增加的,这是因为在系统在进程运行时,会默认打开三个文件,这些文件就是标准输入(0),标准输出(1),标准错误(2)。

从fd的结果来看 为什么是一串连续的数字,这有什么特殊的含义吗? 从我们之前的经验来看,一串连续的数字通常会联想到什么?   没错,就是数组下标,那么这跟数组下标真的有关系吗?如果真的是数组下标,那么有什么用,这就需要明白文件在内存中的体系结构。

文件体系结构(重点)

这里讲的文件体系结构指的是被进程打开的文件,而被进程打开的文件是要被加载的内存的,也就是要在内核中创建一个管理文件的数据结构,更重要的是,既然是被进程所打开,那么就需要被进程所管理起来。

而进程的管理模块是我们熟的不能再熟的PCB(process control block) ,那么有什么办法可以储存文件的几乎所有内容呢? -> 答案是struct 结构体 ,而这个结构体叫做struct file{...} ,这个结构体包含了一个文件的几乎所有内容。

但是一个进程只能打开一个文件吗?  肯定是不止的,光进程打开的默认三个文件标准输入输出、错误就有三个文件,所以一个进程是可以打开多个文件的,而进程与被打开的文件的比例就是1:n,所以我们就又需要一个结构体来管理所有的打开的文件,这个结构体叫做files_struct,并且这个结构体是被存储于进程的PCB之中的,所以就有了这么一个对应关系

struct task_struct(PCB)->struct files_struct->struct file

files_struct储存多个struct file是通过一个指针数组来完成的,而这个指针数组,每个元素都是存储着struct* file,那么这个时候fd充当下标就再合适不过了!

 

重定向

对于fd文件描述符的作用我们已经知道了,它是被files_struct 用来找对应的文件的,那么我们来看下面比较有意思的现象。

先将fd为1的文件关闭,也就是标准输出文件关闭,然后再打开log.txt文件

 

[fengjunzi@VM-4-2-centos lesson14_fd]$ ./myfile 
[fengjunzi@VM-4-2-centos lesson14_fd]$ ll
total 24
-rw-rw-r-- 1 fengjunzi fengjunzi   22 Jun  7 18:27 log.txt
-rw-rw-r-- 1 fengjunzi fengjunzi   65 Jun  7 13:03 Makefile
-rwxrwxr-x 1 fengjunzi fengjunzi 8608 Jun  7 18:27 myfile
-rw-rw-r-- 1 fengjunzi fengjunzi  340 Jun  7 18:27 myfile.c
[fengjunzi@VM-4-2-centos lesson14_fd]$ cat log.txt 
hello world
hello 123

 这个时候运行程序发现并没有打印hello world 和 hello 123 在屏幕上,并且再查看log.txt的内容,发现竟然写到了log.txt 里面,这是怎么一回事?

close(1)关闭的是标准输出,那么关闭的是stdout吗?  这是不准确的,因为stdout是FILE*类型,而FILE是C语言定义的,那么系统是认fd还是认FILE? 而stdout要跟标准输出要有关联,那么C语言一定对stdout进行了fd的封装,并且stdout的fd一定是1 ,所以这里我们虽然close(1),但是stdout仍然存在,且stdout的fd仍然是1,但是stdout已经不再指向的是标准输出了,那是指的什么?  ->  从结果来看,这时候的stdout指向的是log.txt文件。

为什么会指向log.txt?因为我们先关闭了fd = 1 ,而在我们打开新文件的时候,是会先从头检查fd_array是否存在空指针,如果有空指针,就会把该位置的fd分配给那个文件,所以这个时候log.txt就顶替了stdout的 fd,而printf,和fprintf无不是针对fd = 1 的文件进行写入!

那么这种现象叫做什么?是不是很像输出重定向?那么输出重定向的实现就是我们上面所写的那样吗? 不是,因为系统提供了一个接口来更好的实现这个功能!

而通过这种方式,我们如果先close(0),再调用scanf,是不是就相当于输入重定向了?

dup2系统调用

 

dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following:

 *  If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.

 *  If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

翻译过来就是使newfd被拷贝于oldfd,拷贝的是什么,当然是文件的内容,newfd指向的文件内容会被拷贝成oldfd的文件内容。

通过这个接口就能更好的实现输入、输出、追加重定向,因为如果使用上面的那种还需要关闭一个文件,更加麻烦。

输出重定向

 

 

追加重定向

 

输入重定向

 

 

总结

本篇文章,主要讲解了被打开的文件在内存内核中被存储的数据结构,详细讲解了其体系结构,并且讲解了fd文件描述符在整个体系结构的作用,用于作为下标访问对应文件内容。

还讲解了系统提供的dup2接口的作用,以及如何调用dup2 实现输入、输出、追加重定向。

但是,对于文件我们仍然有许多疑问,例如文件缓冲区,还有struct file 存储的一些什么标志性内容,这些我打算放在下一篇文章来进行详细讲解。

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

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

相关文章

WPF 如何实时查看页面元素如何使用实时可视化树

文章目录 往期回顾可视化页面元素如何使用调试工具 总结 往期回顾 WPF 学习:如何使用实时可视化树,照着MaterialDesign的Demo学习 可视化页面元素 我们知道,网页的页面元素是可以通过按F12查看代码。查看到页面元素的。 WPF也有类似的工具…

基于相位共轭法的散射聚焦成像研究-Matlab代码

▒▒本文目录▒▒ 一、引言二、相位共轭法散射聚焦成像Matlab仿真三、参考文献四、Matlab程序开发与实验指导 一、引言 一直以来,研究人员致力于分析造成散射的原因、随机介质性质以及各种散射光的特征,并且研究透过散射介质成像。1990年,I.…

模型剪枝:给模型剪个头发

本文来自公众号“AI大道理”。 深度学习网络模型从卷积层到全连接层存在着大量冗余的参数,大量神经元激活值趋近于0,将这些神经元去除后可以表现出同样的模型表达能力,这种情况被称为过参数化,而对应的技术则被称为模型剪枝。 网…

在价格战中苦苦挣扎的小鹏汽车和蔚来,哪个是最好的电动汽车股?

来源:猛兽财经 作者:猛兽财经 总结: 从长期来看,小鹏汽车(XPEV)的基本面优于蔚来(NIO),小鹏汽车目前的估值也更有吸引力,在全球电动汽车行业中也具有更好的长期投机性。 猛兽财经的投资组合中其中有一部分…

断更两个月的感悟

清明时节雨纷纷, 路上行人欲断魂, 借问酒家何处有, 牧童遥指杏花村。 1.断更 武汉的三月和四月是个多雨的季节,这样的天气经常让我患得患失,由于一些原因(后文再详细说明),不知不觉…

【Linux】分析Fuse中libfuse源码

在Linux中,我们可以使用FUSE来进行自定义用户态文件系统的实现。编译example中的示例是学习FUSE的第一步,本文侧重于剖析FUSE的client端的源码。 文章目录 (一) 下载libfuse源码,避免重复造轮子(二&#xf…

什么是WePY?

WePY(微信小程序开发框架)是一个基于组件化开发思想的微信小程序开发框架。它类似于Vue.js框架,通过封装小程序原生的API,提供了更加简洁、高效的开发方式。 WePY的主要特点包括: 组件化开发:WePY将页面拆…

分布式锁原理与实战二:公平锁和可重入锁的原理

在单体的应用开发场景中,涉及并发同步的时候,大家往往采用synchronized 或者 Lock 的方式来解决多线程间的同步问题。但在分布式集群工作的开发场景中,那么就需要一种更加高级的锁机制,来处理种跨JVM 进程之间的数据同步问题&…

论证有效性写作模板

析错口诀: 1.概念不明确,我就说它概念模糊,并做不利它的解释。【有概念模糊之嫌,A是理解1?还是理解2?】 2.概念有变换,我就说它混淆概念,并指出混淆的环节。(概念推概念&…

华为OD机试真题 Java 实现【数列描述】【2023 B卷 100分】,附详细解题思路

一、题目描述 有一个数列a[N] (N60),从a[0]开始,每一项都是一个数字。数列中a[n1]都是a[n]的描述。其中a[0]1。 规则如下: a[0]:1 a[1]:11(含义:其前一项a[0]1是1个1,即“11”。表示a[0]从左到右,连续出…

【数据结构】图的定义、存储

对王道数据结构选择题做错和不清楚的题的简单纠错 图的定义 一个有n个顶点和n条边的无向图一定是有环的 一个无向图有n个顶点和n-1条边,可以使它连通单没有环,若再加一条边,则会形成环 若图中顶点数为n,则它的生成树有n-1条边&am…

网际互联及OSI七层模型:

网际互联及OSI七层模型: 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 物理层 作用:定义一些电器,机械,过程和规范,如集线器; PDU(协议数据单元):bit/比特 设备&#xff…

分布式锁原理与实战三:ZooKeeper分布式锁的原理

目录 ZooKeeper分布式锁的原理 ZooKeeper的每一个节点,都是一个天然的顺序发号器。 ZooKeeper节点的递增有序性,可以确保锁的公平 ZooKeeper的节点监听机制,可以保障占有锁的传递有序而且高效 ZooKeeper的节点监听机制,能避免羊群…

STM32开发——定时器led、PWM呼吸灯

目录 1.定时器控制LED亮灭 2.PWM呼吸灯——定时器 1.定时器控制LED亮灭 定时器分类: 基本定时器(TIM6~TIM7) 通用定时器(TIM2~TIM5) 高级定时器(TIM1和TIM8) 通用定时器介绍: 16 …

jenkins接口自动化测试,allure报告怎么清楚上一个项目的用例报告?

持续集成(CI Continuous integration/CD Continuous Deployment)的含义其实是在研发过程中团队开发成员持续性的将他们的工作集成到一个完整流程中,通常每个成员每天至少集成一次,每次集成都通过自动化的构建(包括编译,发布&#…

【数据分享】1929-2022年全球站点的逐月平均降水量(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,说到常用的降水数据,最详细的降水数据是具体到气象监测站点的降水数据! 之前我们分享过1929-2022年全球气象站点的逐月平均气温、逐月最高气温…

【Windows】解决无线网卡TL-WN823N免驱版无法上网的问题

【Windows】解决无线网卡TL-WN823N免驱版无法上网的问题 1、背景2、解决办法3、查看适配器 1、背景 下午去前台领了一个"300M无线USB网卡"。 插到台式机上发现不能跳出WLAN网络信号。 我观察到每次插入无线上网卡,在window设置–>设备–>其他设…

员工资料导入

人事管理项目-员工资料导入 后端接口实现前端实现 既然有员工资料导出需求,当然也就有导入需求。对前端而言,员工资料导入就是文件上传,对后端而言,则是获取上传的文件进行解析,并把解析出来的数据保存到数据库中。 后…

Springboot实验二(用配置文件的方式整合Mybatis)仅供参考!

&#xff08;1)articleList.html 效果如下: <!DOCTYPE html> <html lang"en" xmlns:th"http://www.thymeleaf.org/"> <head> <meta charset"UTF-8"> <title>article 列表</title> </head> <body…

数论与组合数学 期末总结(未完

自然数的基本性质 数学归纳法(Principle of Mathematical Induction) n n 0 nn_{0} nn0​时成立&#xff0c;且 n k nk nk成立 ⇒ n k 1 \Rightarrow nk1 ⇒nk1成立&#xff0c;则定理对 n ≥ n 0 n\ge n_{0} n≥n0​成立良序定理(Well Ordering Principle) 每个非空集合…