【基础IO⑧】:文件描述符fd(进程与文件的联系)
【基础IO⑧】:进程与文件之间的联系(文件描述符fd)
- 一.前言探讨[进程与文件关系]
- 二.C语言文件操作
- 三.系统文件调用
- 1.open/write
- 四.文件描述符fd
一.前言探讨[进程与文件关系]
我们首先了解一些基本的认识:
1.文件包括文件内容和文件属性
2.文件分为打开文件和没有打开文件。
3.打开的文件是谁打开的呢?又是如何打开的呢?这是我们本篇的重点处理问题。
4.没有打开的文件在哪里放着呢?
对于打开的文件我们重点想了解是谁打开的,并且是如何打开的。对于没有打开的文件我们重点想了解这些没有被打开的文件在哪里!
1.打开的文件的操作肯定是我们写代码才能操作,所以也就是我们的程序即进程!是进程打开文件。
2.对于没有打开的文件肯定很多,那这些文件是如何被分门别类的放置好的呢?这是我们要探讨的问题,因为我们想对这些未打开的文件快速的进行增删查改。
进程打开了文件,本质上就是要研究进程和文件之间的关系。
要想访问一个文件,首先需要将文件加载到内存里,并且一个进程可以打开多个文件,所以操作系统内部肯定存在很多被打开的文件!那么这些被打开的文件操作系统也需要对他们进行管理。通过先描述再组织的方式进行管理---->每一个被打开的文件操作系统都会给它创建一个文件对象,这个对象包含文件的很多属性。
所以综上:我们要想探讨一个被打开的文件,本质上是探讨进程与文件之间的关系即------->进程PCB与文件对象之间的关系。
二.C语言文件操作
C语言的常见文件操作就是fopen fwrite,fread fclose等打开文件写入文件输出文件等操作。
对于fopen(参数1,参数2)的使用很简单,就是打开某个路径下的文件,以什么样的方式打开.

所以如果不指定文件在哪个路径下,系统会默认将当前进程的路径添加上去,也就是在当前进程目录下创建。
所以如果我们将进程的当前目录修改,就可以将文件新建到别的地方了。
1.‘w’就是以写的方式打开。不过要注意w在写入之前,都会对文件进行清空操作。比如像重定向里的,打开文件但不往里面写,就会直接清空文件,说明重定向操作里面打开文件的方式就是w。
2.‘a’也是写入操作,只不过在打开文件时不会清空文件,而是直接追加在内容末尾。
3.这里还有一个问题:就是当使用fwrite时,后面计算字符串的大小需不需要+1,因为\0的原因就很困扰,为什么有时加1有时不加1呢?
首先我们要明白,字符串是C语言规定出来的,它的后面必须要有\0。但文件就不认识C语言,文件只需字符的内容就可以了,所以当我们往文件里写入时字符串时,都不需要加+1,直接计算字符串的长度即可。
还有一个知识:那就是C语言下,会默认给我们打开3个标准输入输出流:
三.系统文件调用
文件其实是在磁盘上的,磁盘又是属于硬件设备。操作系统的构成,用户层在最上面,硬件在最下面,用户要想访问硬件必须要通过操作系统,而操作系统又因为安全性只会给你提供系统调用接口来访问。
所以所有的库函数,只要要访问硬件资源,就一定要封装系统调用接口。

1.open/write

有两个open接口,这两个的区别在于第三个参数有和没有。
对于已经存在的文件,肯定有它自己的权限设置,这样才可以被访问,所以当一个文件被创建时,必须要设置这个文件的权限属性。
而第三个参数就是用来设置权限的。所以第一个open是用来打开已经存在的文件,而第二个open是用来打开创建一个没有存在的文件的,并设置这个文件的权限。我们主要用三个参数的open调用接口。
open系统调用接口的参数第一个就是文件路径,第二个参数是打开的方式,第三个参数是用过给这个文件设计权限的。返回值是int类型
open是系统调用接口,它有自己的打开文件的方式,它是采用比特位方式的标志位传递参数从而采用不同的打开方式。
O_WRONLY表示只写形式
O_CREAT表示如果文件不存在就创建
O_TRYNC表示打开文件之前先清空文件
O_APPEND表示追加,不清空。

所以C库函数fopen里封装着open系统调用函数,"w"方式就是O_WRONLY, O_CREAT, O_TRYNC三种方式组合,"a"方式就是
O_WRONLY, O_CREAT, O_APPEND三种方式组合。
fopen封装着open这个我们应该能理解,不过你没有注意到open的返回值是int类型,而fopen的返回值确实FILE类型,int类型和FILE类型之间有什么关系呢?
四.文件描述符fd
我们知道只要打开一个文件,操作系统就要给这个打开的文件创建个文件对象struct file。这个对象描述着文件许多属性。文件对象之间用链表连起来。这样操作系统对于文件的管理,就转换为对链表的增删查改了。
我们前面也说过一个进程可以打开多个文件,所以操作系统内部肯定有许多被打开的文件,那么进程是怎么知道它打开的是哪个文件呢?
其实进程PCB里存在一个指针对象,叫做struct file_struct对象。
它指向的是一个结构体对象,这个结构体里面存着一个数组struct file arr[],这个数组叫做文件描述符表,里面存的都是文件对象的地址。当进程要打开一个文件是,操作系统首先会为这个文件创建struct file对象。然后就会将这个对象地址存放在文件描述符表里。当又打开一个文件,就依次将文件对象的地址放进数组里面,最后返回该数组的下标给进程。最后调用open打开创建一个文件后,就会获得一个int类型的下标。所以本质上这个int类型的返回值就是数组的下标。也就是文件描述表的下标。而进程就是通过这个下标再次找到被打开的文件的。
所以这个下标也叫做文件描述符。本质上就是文件对象在文件描述表里位置。
所以进程是通过文件描述符fd来找到被打开的文件的。这也是为什么open返回值为什么是int类型了。
因为进程可以打开多个文件,所以这里采用的引用计数的方式进行关闭,每个文件对象都有一个计数器,当进程close这个文件时,计数器就减减,减完后如果计数器不为0,则说明还有其他进程在使用这个文件,则不真正关闭文件,当计数器为0时才真正的关闭文件。

open返回的是文件描述符fd。但fopen返回的确实FILE类型这是怎么回事呢?
其实在操作系统它只认识文件描述符fd,并不认识FILE。进程与文件之间本质是通过数组下标来联系的。
所以不管FILE是什么,它内部肯定封装着文件描述符fd。FILE其实一个结构体对象。后面我会详细介绍它。
所以对于文件操作来说,进行了两次封装,一次是函数层面的封装:库函数封装系统调用,一次是类型方面封装:FILE类型里面封装fd类型。
到这里我们就可以验证一个现象了:
你说C语言默认给我们打开了三个标准输入输出流,你怎么证明呢?
文件既然被打开了,操作系统就会给它创建结构体对象struct file。并且会将它的地址放入文件描述符表里,一开始文件描述符表里一个都没有,现在这三个放进去,应该分别对应的数组下标是 0 1 2.所以我们可以观察他们的文件描述符是什么。

相关文章:
【基础IO⑧】:文件描述符fd(进程与文件的联系)
【基础IO⑧】:进程与文件之间的联系(文件描述符fd) 一.前言探讨[进程与文件关系]二.C语言文件操作三.系统文件调用1.open/write 四.文件描述符fd 一.前言探讨[进程与文件关系] 我们首先了解一些基本的认识: 1.文件包括文件内容和文件属性 2.…...
搭建WAMP网站教程(windows+apache+mysql+php)
之前为了学习网络安全,从搭建网站学起,对网站运行有个初步的了解。 今天翻到了之前的笔记,顺手发到csdn上了。 搭建网站步骤 一、Apache 安装Apache,下载Apache之后把Apache解压,此处解压到C:\目录下 2.然后要记得安…...
瓦斯抽采VR应急救援模拟仿真系统筑牢企业安全生产防线
矿工素质对安全生产的影响很大。传统的煤矿安全事故培训出于条件差、经验少加上侥幸心理,导致其在教学内容时过于简单且不切合实际,无法真正发挥培训作用。瓦斯检查作业VR模拟实操培训通过真实还原煤矿作业环境,让受训者身临其境地进入三维仿…...
nodelist 与 HTMLCollection 的区别
原地址 https://cloud.tencent.com/developer/article/2013289 节点与元素 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点每个 HTML 元素是元素节点HTML 元素内的文本是文本节点每个 HTML 属性是属性节点注释是注…...
系列十二、过滤器 vs 拦截器
一、过滤器 vs 拦截器 1.1、区别 (1)触发时机不一样,过滤器是在请求进入容器后Servlet之前进行预处理的,请求结束返回也是,是在Servlet处理完后,返回给前端之前; (2)过滤…...
dockerfile运行apk命令卡住的问题解决——更换镜像
在练习docker官方文档关于docker compose初体验(https://docs.docker.com/compose/gettingstarted/)过程中,执行dockerfile命令RUN apk add --no-cache gcc musl-dev linux-headers时,出现卡住的情况,等了几千秒都不行…...
Android - 编译 openssl 踩坑之路
一、简述 如果你想快速在项目中使用上 openssl,可以使用网上其他开发者提供好的预编译库: OpenSSL(All):https://builds.viaduck.org/prebuilts/openssl/OpenSSL(3.1.*) :https://github.com/217heidai/openssl_for_android以上的预编译库可能最低只支持 API 21(即 Andro…...
verdi技巧分享--合并多个fsdb文件、统计信号边沿
文章目录 0 前言1 如何显示信号高位的02 统计信号的上升沿、下降沿3 合并信号4 将多个fsdb文件合并成一个 0 前言 分享几个这段时间学到的verdi操作 1 如何显示信号高位的0 这个可能对一些有强迫症的有帮助吧 nand相关的操作,有一些特定的cmd,比如 r…...
czmq的4版本中CURVE怎么实现的两个程序之间使用的一个证书?
在CZMQ的4版本中,CURVE是一种加密机制,用于在两个程序之间建立安全的连接。要使用CURVE,你需要创建和分发公钥和私钥。以下是一个简单的步骤说明: 首先,你需要为每个程序生成一对公钥和私钥。你可以使用CZMQ的zcert类…...
Spring Boot整合Swagger
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…...
SpringBoot-WebSocket浏览器-服务器双向通信
文章目录 WebSocket 介绍入门案例 WebSocket 介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 应用场景: 视…...
Docker网络模式_Docker常用命令_以及Docker如何给运行的镜像内容连接互联网_Docker网络模式原理---Docker工作笔记004
然后我们来看一下docker的网络模式: 这个docker我们先看一下电脑上的网络,有两个,1个是lo是测试用的一个是enp0s3这个是我们以太网地址,然后我们去: 安装docker 安装后我们再去ip address可以看到多出来一个网络是docker0 这里ip地址是172.17.0.1这个是私有地址外部无法访问 这…...
爬虫项目-爬取股吧(东方财富)评论
1.最近帮别人爬取了东方财富股吧的帖子和评论,网址如下:http://mguba.eastmoney.com/mguba/list/zssh000300 2.爬取字段如下所示: 3.爬虫的大致思路如下:客户要求爬取评论数大于5的帖子,首先获取帖子链接,…...
【Midjourney入门教程2】Midjourney的基础操作和设置
文章目录 Midjourney的常用命令和基础设置1、 /imagine2、 /blend3、 /info4、 /subscribe5、 /settings(Midjourney的基础设置)6、 /shorten 有部分同学说我不想要英文界面的,不要慌: 点击左下角个人信息的设置按钮,找…...
后端使用DES加密,前端解密方法
前言: 现在为了防止用户直接篡改数据会采用加密的方式进行传输,加密的方法有很多种,这篇文章主要讲解下后端使用DES加密的数据传输给前端,前端接收到之后如何去解密。 操作步骤如下: 1.安装crypto-js npm install c…...
chrome 扩展 popup 弹窗的使用
popup的基本使用方法 popup介绍 popup 是点击 browser_action 或者 page_action图标时打开的一个小窗口网页,焦点离开网页就立即关闭,一般用来做一些临时性的交互。 popup配置 V3版本中(V2版本是在 browser_action 中 )&#x…...
Spring Security入门教程,springboot整合Spring Security
Spring Security是Spring官方推荐的认证、授权框架,功能相比Apache Shiro功能更丰富也更强大,但是使用起来更麻烦。 如果使用过Apache Shiro,学习Spring Security会比较简单一点,两种框架有很多相似的地方。 目录 一、准备工作 …...
如何在 Unbuntu 下安装配置 Apache Zookeeper
简介 Zookeeper 是 apache 基金组织下的项目,项目用于简单的监控和管理一组服务,通过简单的接口就可以集中协调一组服务,如配置管理,信息同步,命名,分布式协调。 准备工作 Ubuntu 23.04 或者 20.04访问…...
AI视觉领域流媒体知识入门介绍(二):深入理解GOP
GOP(group of pictures) 在流行的视频编码算法中,都包含GOP这个概念,例如MPEG-2, H.264, and H.265。 背景 关于视频存储和传输的“size”: Resolution 分辨率 Uncompressed Bitrate 未压缩时的比特率 1280720 (720p…...
C++ 代码实例:并查集简单创建工具
文章目录 前言代码仓库代码说明main.cppMakefile 结果总结参考资料作者的话 前言 C 代码实例:并查集简单创建工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) 代码 说明 简单地创建并查集注…...
癫痫手术精准定位:基于脑电信号昼夜节律与多生物标志物的机器学习分析框架
1. 项目概述:当机器学习遇见脑电信号,如何让癫痫手术更精准?作为一名长期耕耘在生物医学信号处理与机器学习交叉领域的工程师,我常常思考如何将算法模型从实验室的“玩具”变成临床医生手中可靠的“手术刀”。癫痫,这个…...
③ AI副业第一步:如何找到适合自己的AI赚钱赛道
③ AI副业第一步:如何找到适合自己的AI赚钱赛道选对赛道,努力才有意义。选错赛道,越努力离钱越远。前言:为什么大多数人AI副业做不起来? 我观察了100想做AI副业的人,失败的原因高度一致: 失败路…...
百考通智能任务书:贴合你的选题,拒绝空话假大空
毕业设计任务书是高校教学管理中的关键环节,它不仅标志着研究工作的正式启动,更是后续开题、实施、论文撰写和答辩全过程的行动依据。然而,许多学生在撰写时常常因不熟悉本专业写作规范、技术表达能力有限,或缺乏权威模板参考而陷…...
告别虚拟机卡顿:在Windows 11的WSL2里搞定Lichee Nano交叉编译环境
告别虚拟机卡顿:在Windows 11的WSL2里搞定Lichee Nano交叉编译环境 对于嵌入式开发者来说,配置开发环境往往是个令人头疼的问题。传统虚拟机方案虽然能提供完整的Linux体验,但资源占用高、启动慢、与宿主系统交互不便等问题一直困扰着开发者。…...
从游戏引擎到仿真平台:手把手教你用AirSim+UE4搭建你的第一个无人机/自动驾驶仿真环境
从游戏引擎到仿真平台:构建AirSimUE4无人机与自动驾驶仿真环境实战指南当游戏引擎遇上机器人算法测试,会碰撞出怎样的火花?微软开源的AirSim项目将虚幻引擎(Unreal Engine)从游戏开发领域引入到自动驾驶和无人机研究的…...
终极Chrome画中画扩展:如何在浏览器中实现高效视频多任务处理
终极Chrome画中画扩展:如何在浏览器中实现高效视频多任务处理 【免费下载链接】picture-in-picture-chrome-extension 项目地址: https://gitcode.com/gh_mirrors/pi/picture-in-picture-chrome-extension 想要在浏览网页、处理文档的同时继续观看视频内容吗…...
开源ELM327 OBD-II适配器:从硬件设计到多协议固件实现全解析
1. 项目概述:开源ELM327 OBD适配器如果你对汽车诊断、数据监控或者嵌入式开发感兴趣,那么自己动手做一个OBD-II适配器绝对是个能让你学到很多东西的硬核项目。今天要聊的,就是一个完全开源的、基于NXP LPC1517微控制器的ELM327兼容OBD适配器。…...
JWT弱密钥爆破实战:从HS256签名原理到CTF权限提升
1. 这不是密码学考试,而是一场“密钥猜谜”实战JWT(JSON Web Token)在现代Web系统中早已不是可选项,而是默认配置。登录成功后返回一串形如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsIm5hbWUiOiLnlKjliYkiLCJpYX…...
AhMyth位置跟踪:GPS定位与地理围栏技术深度解析
AhMyth位置跟踪:GPS定位与地理围栏技术深度解析 【免费下载链接】AhMyth Cross-Platform Android Remote Administration Tool | The only maintained version of AhMyth on github | A revival of the original repository at https://GitHub.com/AhMyth/AhMyth-An…...
掌握Umi-OCR:5分钟上手开源免费离线文字识别工具
掌握Umi-OCR:5分钟上手开源免费离线文字识别工具 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。…...






