<Linux系统复习>文件描述符

news2024/12/20 2:58:45

一、本章重点

1、进程和打开文件的关系

2、简单复习c语言文件操作

3、介绍系统调用:open、clos、write、read

4、理解文件描述符

5、文件描述符分配规则

6、理解stdin、stdout、stderr与fd的关系

7、理解linux下一切皆文件

8、理解重定向的本质

9、理解stdin和stdout的区别

10、理解缓冲区

01 进程和打开文件的关系

1、需要明确一点的是打开文件是由进程打开的,那么进程可以打开多个文件吗?当然可以,打开了多个文件,那么就需要将它们管理起来,操作系统是怎么管理这些打开文件的呢?先创建struct file用来描述打开的文件,然后将多个struct file用指针链接起来。

 那么struct file里面包含了什么呢?

1、部分磁盘文件的属性(权限、路径、最近一次修改时间等)

2、read方法、write方法。

........

关于struct file的疑惑后面会解答。

02 简单复习c语言文件操作

1、fwrite

2、fread

3、fprintf

03 介绍系统调用接口:open 、close、write、read

1、open、close、write

 

可以看到有两个open系统调用,它们是重载关系。

ssize_t 是 typedef int ssize_t

 其中O_WRONLY:代表只写,O_CREATE:代表没有该文件就创建,O_TRUNC:如果写之前文件有内容就清空文件所有内容。

0666代表创建文件的默认权限,但为什么创建出来的demo.txt权限是664?

答案:因为umask为0002,最终权限等于664 & (~002),一般我们创建文件的时候,都会让umask等于0,不用系统的默认权限,因为有的操作系统的默认权限可能不是0002,因此使用umask(0)这个函数调用,可以让我们的程序更完美。

 

我们可以将O_WRONLY、O_CREATE、O_TRUNC看做c语言 “w” 的打开方,

O_WRONLY、O_CREATE、O_APPEND。看做c语言fopen中 “a” 的打开方式。

2、open、close、read

 

04 文件描述符

1、什么是文件描述符。

open系统调用返回的就是一个文件描述符,我们调用write和read也需要文件描述符。

 进程的task_struct中有一个指向struct files_struct结构体的指针,struct files_struct中有一个数组array_fd[ ],该数组存储了该进程打开文件的struct file结构体,所谓的文件描述符,其实是数组下标,进程可以通过数组下标,找到打开文件的结构体,struct file里有文件的读写方法,就能够将进程的数据写到打开文件对于的磁盘文件,或者从磁盘文件读入到进程的数据中。

1、简单介绍:一个磁盘文件被打开,操作系统做了什么?

创建一个struct file内存文件结构,然后将它的地址放入进程的文件描述符表中,最后返回数组下标给用户。

05 文件描述符的分配规则

1、文件描述符的分配规则:优先分配最小的、未分配的数组下标。

为什么这个进程的文件描述符是从3开始的,如果是数组下标的话,不是应该从0开始吗?

答案:0 1 2被分配给键盘、显示器、显示器了。一个进程默认会打开3个流,stdin、stdout、stderr,分别对于0 1 2.

如果关闭0,那么按照规则来说,fd应该是0。

06 理解stdin、stdout、stderr与fd的关系

 stdin是FILE* 类型,那么FILE是什么呢?它是一个结构体。

我们都知道可以这样向屏幕打印字符

 也可以这样向屏幕打印。

 我们也知道c语言接口和系统接口的关系,c语言库函数是对系统接口的一层封装。

 为什么c语言接口要对系统接口进行一层封装呢?

①、系统接口不好用,对使用者要求高一点。

②、对系统接口进行封装,可以使得c语言函数在大多数操作系统都能够运行,移植性好。 

现在我们大概可以猜测出FILE里面包含了fd,如何证明?

07 理解linux下一切皆文件

 驱动层:由于不同厂商制作的硬件可能有差异,操作硬件的方法可能不同,所以在操作系统和硬件之间加了一个驱动层,驱动层提供方法给操作系统,这样不管什么硬件,只要安装了相关驱动,一般而言操作系统都能够使用该硬件。

struct file是打开文件的数据结构,进程可以通过fd找到struct file,然后通过struct file里面的方法可以对硬件或者普通文件进行读写,但对每个硬件或者普通文件的读写方法肯定是不同的,因此就需要别人提供方法的地址给它,struct file就不用管它要调用哪种方法了,而是直接使用read和write。这种调用同一个函数,通过传的函数地址不同,展示的功能不同,不就是多态吗?那么struct file就能够以一种统一的视角看待硬件和普通文件了,可以把键盘、显示器、网卡、磁盘都看做文件。

08 理解重定向的本质

1、先复习一下从定向

①、输出从定向

②、输入从定向

③、追加从定向

 

2、看看下面的这种现象

如何理解这种现象?

 可以把printf(“%s”,"谢谢你\n")与fprintf(stdout,“%s”,"谢谢你\n")等价,又因为stdout包含了1,本来1是指向显示器的,关闭1后打开log.txt,根据文件描述符的分配规则,1指向的是log.txt,可是stdout可不管你是不是显示器,我只负责向文件描述符为1的打开文件写数据。

自然printf输入的数据到了log.txt磁盘文件中,这就是重定向的底层原理。

2、那么只能通过关闭0、1文件描述符,打开新的文件来实现重定向吗?我们还可以使用dup2()来实现重定向。

 注意的是:它是将oldfd拷贝到newfd,不要记反了。

 

09 stdin和stdout的区别

1、现象一

 似乎并没有什么区别,只要一个stdout不就好了吗?

 一个打印到屏幕上,一个输出到log.txt文件里,如何解释这种现象?

解释:

因为重定向的缘故,1文件描述符不再指向显示器,而是指向log.txt,因此标准输入会打印到log.txt中,但2文件描述符并未重定向,依然指向的是屏幕,因此标准错误打印到屏幕上。从这里我们也知道了,>重定向的只是1文件描述符。

2、现象二

 

10 缓冲区

1、一个令人疑惑的现象

 为啥无法打印出hello world?

解释:printf是c语言接口,默认向stdout流中输出数据,也就是向屏幕输出数据,但由于有c语言缓冲区的因素,该缓冲区刷新策略依靠内存文件指向的对象,如果指向屏幕,那么采取行刷新,如果是普通文件,则采取全刷新。close(1),然后再打开log.txt,导致刷新对象由显示器变为普通文件,因此printf(“hello world”)的内容会保存在用户缓冲区(c语言缓冲区),最后因为你又关闭了1文件描述符,导致用户缓冲区无法通过1描述符将数据刷新到log.txt中。

如果最后没有关闭close(1),在进程结束的时候,操作系统会自动将进程用户缓冲区的数据刷新到文件对象中。

2、关于close()和dup2的理解

dup2(fd,1)是将fd的内容拷贝到1中,假设fd是3,那么1和3都是指向新打开的文件的,也就是说你既可以通过1传入数据,也可以3来传入数据。

close(fd),相当于将arr_fds[ fd ]置为0,并对指向的内存文件中的引用计数--,如果该计数为0,则需要释放该内存文件。

对于dup2(fd,1),如果不需要fd和1同时指向log.txt文件,则可以关闭fd文件描述符。这个时候不能关闭1文件描述符,如果关闭,相当于dup2()调用和没调用是一样的。

3、综合题

  

解释:write直接输出到屏幕文件,而其他则输出到c语言提供的缓冲区中没有打印出来,由于进程的独立性,每个进程都有自己独立的缓冲区,同时子进程会继承父进程的缓冲区数据,最后在两个进程终止时,操作系统会将进程缓冲区的数据刷新到对应的文件中。

4、模拟实现一个perror

 

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

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

相关文章

《吉师作业》(1)之我是web手为啥让我学C

前言 🍀作者简介:吉师散养学生,为挣钱努力拼搏的一名小学生。 🍁个人主页:吉师职业混子的博客_CSDN博客-python学习,HTML学习,清览题库--C语言程序设计第五版编程题解析领域博主 🫒文章目的:我不…

freeRTOS学习(二)

堆内存管理 先决条件 FreeRTOS是作为一组C源文件提供的,因此成为一个合格的C程序员是使用FreeRTOS的先决条件。 动态内存分配及其与FreeRTOS的相关性 内核对象:如任务、队列、信号量和事件组。为了使FreeRTOS尽可能易于使用,这些内核对象不…

科普一下MTU是什么,如何设置MTU

欢迎来到东用知识小课堂,下面我们就来科普一下一下MTU是什么,如何设置MTUMTU是最大传输单元的意思,代指一类通讯协议某一层上所能通过的最大数据包大小(以byte为单位)。最大传输单元这一主要参数一般与串行通讯接口相关(网络接口卡、串口等)。…

【Vue实用功能】彻底搞懂Vue中的Mixin混入

前言 有些小伙伴接手别人的Vue项目时,看到里面有个Mixin文件夹,可能会云里雾里的状态,今天我们来好好聊聊Mixin,争取以后不再云里雾里。 一、什么是Mixins? Mixins(混入):当我们存在多个组件中的逻辑或者…

MySQL总结

文章目录一.SQL语句简介1.什么是SQL?2.SQL分类二.MySql常用数据类型三.数据库操作1.创建数据库2.查询和删除数据库3.备份/恢复数据库四.表操作1.创建表2.修改/查看表五.CRUD语句1.Insert语句2.Delete语句3.Update语句4.Select语句五.函数1.统计函数count2.字符串相关…

for in和for of

文章目录二者在什么情况下可以使用for ... in什么是可枚举的属性?for...of什么是可迭代的数据?总结二者在什么情况下可以使用 for … in 可以用在可枚举的数据,如: 对象数组(循环的是索引)字符串 什么是…

ESP8266-Arduino网络编程实例-发送邮件(基于SMTP)

发送邮件(基于SMTP) 本文将演示如何使用ESP8266发送邮件。实例中将使用SMTP(Simple Mail Transfer Protocol)协议通QQ邮箱向指定邮箱发送邮件。 1、设置QQ邮箱第三方服务 1)第一步:注册一个QQ邮箱 2)第二步:开启QQ邮箱的第三方服务 1、硬件准备 ESP8266 NodeMCU开发…

高通Android随身WIFI屏蔽商家远程控制断网

部分随身WIFI商家后台会监测用户是否使用的是自家的eSIM,若使用了外置卡槽或eSIM的ICCID改变就会断网,主要表现是先联网后突然变成飞行模式,或联网后开热点变飞行模式。这就是商家后台做了监测,检测到异常就断网。我们的主要解决思路就是禁止随身wifi连接商家的远程服务器,…

pytorch中一维卷积,二维卷积,三维卷积,层次特征注意力

一维卷积 一维卷积操作常用作文本数据或者序列数据的处理。这里以文本数据为例进行讲解。 下图左边是一个文本矩阵,是将这句话‘I like this movie very much!’转换为计算机可以处理的语言。对于宽度,可以认为是词向量的维度,高度可以表示为这个句子的最大长度,从这里可…

上手Python之set(集合)

为什么使用集合 我们目前接触到了列表、元组、字符串三个数据容器了。基本满足大多数的使用场景。 为何又需要学习新的集合类型呢? 通过特性来分析: 列表可修改、支持重复元素且有序 元组、字符串不可修改、支持重复元素且有序 有没有看出一些局限&…

JavaEE在线学习系统的设计与实现

目 录 摘 要 i Abstract ii 第1章 概论 1 1.1 课题背景 1 1.2 课题意义 2 1.3开发工具及技术 2 1.3.1 MyEclipse 2 1.3.2 ToMcat 2 1.3.3 SqlServer 2 1.3.4 JSP 3 1.3.5 Servlet 3 第2章 可行性分析及总体设计原则 5 2.1可行性分析 5 2.1.1技术可行性 5 2.1.2经济可行性 5 2.1…

Python - Numpy库的使用(简单易懂)

目录 numpy多维数组——数组的创建 1、array函数创建数组对象 2、通过arange、linspace函数创建等差数组对象 3、通过logspace函数创建等比数列数组 函数 zeros ones diag eye full numpy多维数组——生成随机数 函数 seed rand randn randint 函数 binomial normal 和…

【算法篇-搜索与图论】适合算法入门小白理解的深度优先搜索(DFS )以及解决全排列数字

目录1.什么是深度优先搜索(DFS)2.结合例子看DFS2.1 全排列数字结语该文章部分内容摘抄自 啊哈磊老师的《啊哈!算法》 一本对算法新手非常友好的书,非常推荐新手去阅读! 1.什么是深度优先搜索(DFS&#xff0…

【阿里云】短信服务

目录 1. 前置技术:阿里大鱼 1.1 概述 1.2 开通 1.3 签名管理 1.3.1 签名概述 1.3.2 添加签名 1.3.3 使用 1.4 模板管理 1.4.1 模板概述 1.4.2 添加模板 1.4.3 使用 1.5 在线文档 1.5.1 打开在线文档 1.5.2 使用在线文档 1.6 使用工具类发送短信 1.7…

基于混合VNS(变邻域搜索算法)的PSO(粒子群优化算法)的任务分配问题(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

数据分析 | Pandas 200道练习题,每日10道题,学完必成大神(3)

文章目录1.读取本的数据集2.查看数据的前5行3.将salary列的数据转换为最大值和最小值的平均值4.将数据根据学历进行分组计算平均值5.将createTime列转换为月日6.查看所索引,数据类型和内存信息7.查看数值型列的汇总统计8.新增一列根据salary将数据分为三组9.按照sal…

【Day31】力扣算法(超详细思路+注释)[1441. 用栈操作构建数组 ] [621. 任务调度器]

您的点赞,收藏以及关注是对作者最大的鼓励喔 ~~ 刷题打卡,第 三十一 天题目一、1441. 用栈操作构建数组题目二、621. 任务调度器题目一、1441. 用栈操作构建数组 原题链接:1441. 用栈操作构建数组 题目描述: 给你一个数组targe…

5 个 Flutter VSCode 技巧和窍门,你可以马上使用!

5 个 Flutter VSCode 技巧和窍门,你可以马上使用! 前言 今天,我将向你展示 5 个非常有用的 Flutter 技巧,你可以立即应用到你的项目中。我不会给你任何软件包或扩展,但非常简单,但非常有用的技巧&#xff0…

【大厂高频真题100题】单词拆分 真题练习第7题 持续更新~

单词拆分 描述: 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入: s = "leetcode", wordDict = ["leet&q…

德邦股份第三季营收80亿:净利2.56亿 京东控制72%股权

雷递网 雷建平 10月28日德邦物流股份有限公司(证券代码:603056,证券简称:德邦股份)今日发布财报。财报显示,德邦股份2022年前9个月营收为228.17亿元,较上年同期增长1.14%;净利为3.5亿…