文件底层的深入理解(1)

news2024/9/23 13:29:36

一、文件学习的简单铺垫

        我们都知道,文件等于文件内容加上文件属性。访问文件之前都得先通过进程才能打开相应的文件,一个进程可以打开多个文件。修改文件,都是通过执行代码的方式完成修改。要对文件进行修改(或其他操作),文件就必须事先被加载到内存当中。从前面的叙述我们可以知道,在一定的时间段内,系统可能呢存在多个进程,也一定会存在多个被打开的文件,操作系统通过先描述再组织的方式对这些文件进行统一的管理。所以,在操作系统内部,一定会存在描述被打开文件的结构体,并用其定义对象。没有被打开的文件就存储在磁盘当中。

二、对文件路径产生与由来的理解

        从上面的铺垫可以看出,文件与进程一定是密切相关的,下面我启动一个进程,在这个进程中创建了一个文件并向其中写入内容:

并获得该进程的pid:

        在proc目录中找到该进程对应的所有属性,其中就可以看到该进程所处的目录。进程在打开时,会自动记录它当前所处的目录,所以在该进程中创建的文件如果不带路径,那么自然而然地就被创建在了进程所在的目录中。这就是文件路径的产生与由来。 

三、文件的系统调用接口

        我们都知道,上层的语言是无法直接访问底层的硬件的,要访问硬件必须通过操作系统,所以操作系统就必须提供所谓的系统调用函数来供用户使用。那为什么我们看不到系统调用函数呢?原因是因为在语言层面上已经封装了系统调用函数。就比如说fopen函数就封装了open函数。下面我会以open函数对系统调用函数做一些简单的介绍。

 open函数

        我们可以看到open函数中有flags这个参数,其实flags这个参数你可以把它看成32个比特位,其中每一个比特位代表不同的权限(类似于位图),所以我们就可以通过与或操作对flags设置不同的值,进而设置文件的读写权限。

        mode是权限的意思,如果一个文件事先还没有被创建出来,就必须在创建的时候通过设置mode指明它的权限。

        O_WRONLY表示只写权限位(注意这里的只写与C语言中的w权限不一样,O_WRONLY并不会将原有的文件内容清空再写入,而是直接在文件的开头进行覆盖式写入,如果要将原有的文件内容清空再写入需要再或上O_TRUNC),O_CREAT表示文件不存在就创建权限位,0666表示我设置的权限位(也会受umask掩码的约束),如果一个文件本来就已经存在了,在打开的时候就不用传递权限了。这样也可以创建出一个文件。

 四、文件描述符详解

        文件描述符就是指的上面代码中open函数返回的fd这个int类型的值。在C语言中,描述文件的FILE类型其实就是一个结构体,该结构体中封装了特定的fd。在系统当中,一定会存在多个被打开的文件,操作系统通过先描述再组织的方式(创建出struct file结构体)对这些文件进行统一的管理,而一个进程也可能会打开多个文件,所以在描述进程的task_struct结构体中就存在一个指针struct files_struct* files,这个指针指向一个结构体,在进程创建的时候这个结构体就被创建出来了,在这个结构体中包含了很多字段,其中就有一个struct file* fd_array数组(也叫做文件描述符表),保存了该进程所打开的所有文件的地址,这样,该数组的数组下标就和文件的地址产生了一一对应的关系,而这里的数组下标就是fd。

        所以我们打开文件的本质就是先在磁盘当中找到这个文件,然后将其内容和属性加载到内存当中,创建出struct file结构体,将结构体内的属性、方法、缓冲区全部初始化,再将struct file结构体链入到操作系统管理被打开的struct file结构体链表中,再将struct file结构体的地址填入到对应进程中的struct file* fd_array数组,最后将数组下标返回给用户。最后我们总结一下:其实文件描述符就是数组下标。正如下面这个图所示:

        所以现在我们就可以大致说一下,向文件中写入内容(write函数),本质就是通过fd找到对应的struct file结构体,将数据写入struct file结构体对应的缓冲区中,再由操作系统帮我们把数据写入磁盘当中。从文件中读内容(read函数),本质就是通过fd找到对应的struct file结构体,从该结构体的缓冲区中读取数据,如果缓冲区中没有对应的数据,操作系统就会从磁盘中加载对应的数据到缓冲区中,再将数据根据上层给的地址拷贝到内存当中,文件的内容就被读到了。上面所述内容在操作系统源代码中也是可以得到验证的。

 

 

五、总结:理解一切皆文件

        各个硬件在底层的读写方法肯定都是不一样的,在创建struct file结构体时,需要创建read和write两个函数指针,在调用不同的硬件时,只需要让函数指针指向不同的函数,返回的是都是read或write方法,从而屏蔽了底层硬件上的差异,使得linux下一切都可以当成文件来看待。如图所示:

 

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

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

相关文章

Java 数组(详细)

目录 一、数组的概述 1. 数组的理解: 2. 数组相关的概念: 3. 数组的特点: 4. 数组的分类: 5.数据结构: 二、一维数组 1. 一维数组的声明与初始化 2. 一维数组元素的引用: 3. 数组的属性&#xff1…

微信小程序,h5端自适应登陆方式

微信小程序端只显示登陆(获取opid),h5端显示通过账户密码登陆 例如: 通过下面的变量控制: const isWeixin ref(false); // #ifdef MP-WEIXIN isWeixin.value true; // #endif

力扣hot100题解(python版44-47题)

44、二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例 1: 输入:root [3,1,4,null,2], k 1 输出:…

FHE 的应用场景

参考文献: [MSM22] Marcolla C, Sucasas V, Manzano M, et al. Survey on fully homomorphic encryption, theory, and applications[J]. Proceedings of the IEEE, 2022, 110(10): 1572-1609. 文章目录 FHEFirst GenerationSecond GenerationThird GenerationFour…

编码规则转换

思考: 如何将一个机内码转换为区内码? 只要将机内码减去 A0A0 就可以啦 如果只让我们用加法器来解决呢? 注意我们的数据占用了 32 位,如果想用补码进行减法运算的话,符号位怎么办??&#xf…

2199. 骑士共存问题(最小割,最大权独立集,二分图)

活动 - AcWing 在一个 n∗n 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。 棋盘上某些方格设置了障碍,骑士不得进入。 对于给定的 n∗n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个…

2024年腾讯云优惠券_代金券_云服务器折扣券免费领取链接

腾讯云优惠代金券领取入口共三个渠道,腾讯云新用户和老用户均可领取8888元代金券,可用于云服务器等产品购买、续费和升级使用,阿腾云atengyun.com整理腾讯云优惠券(代金券)领取入口、代金券查询、优惠券兑换码使用方法…

UE5中实现后处理深度描边

后处理深度描边可以通过取得边缘深度变化大的区域进行描边,一方面可以用来做角色的等距内描边,避免了菲尼尔边缘光不整齐的问题,另一方面可以结合场景扫描等特效使用,达到更丰富的效果: 后来解决了开启TAA十字线和锯齿…

【go从入门到精通】go包,内置类型和初始化顺序

大家好,这是我给大家准备的新的一期专栏,专门讲golang,从入门到精通各种框架和中间件,工具类库,希望对go有兴趣的同学可以订阅此专栏。 go基础 。 Go文件名: 所有的go源码都是以 ".go" 结尾&…

latex宏包pythontex使用简明手册

文章目录 1.背景2. 基本示例2.1 hello world2.1.1 代码与输出结果2.1.2 说明2.1.3 如何编译使用了pythontex宏包的Latex文档2.1.4 如何既输出python代码又输出代码执行结果 2.2 在Latex中嵌入python变量的值2.2.1 示例代码与文档输出2.2.2 说明 2.3 在latex文档中输出控制台会话…

2.29号的复盘开始商城项目的规格如何设施的方式

第五次设计方式 我本来想的是,按照对于的组方式解拆分,通过分组处理的内存不同查询对应的手机上 出现问就是这里 对于的组相应规格相应里面有对于的价格,价格也就相同,无法进行区分 查询出来的对应的结果 还是没有办法具体拆分…

现货大宗商品发售平台搭建须知

在搭建现货大宗商品发售平台时,需要考虑以下关键因素: 目标市场分析:首先要明确你的平台将服务于哪些大宗商品市场,如农产品、金属、能源等。了解这些市场的特点、参与者、交易规则等,有助于你设计出更符合市场需求的…

解析/区分MOS管的三个引脚G、S、D(NMOS管和PMOS管)

MOS管的三个引脚分别是Gate(栅极)、Source(源极)和Drain(漏极)。以下是详细介绍: Gate(栅极)。这是控制MOS管开关的关键引脚,用于控制电流的流通。Source&…

pikachu验证XXE漏洞

先随便输入一个内容查看 接下来用bp抓包看下参数 有个xml参数&#xff0c;而且Content-Type: application/x-www-form-urlencoded&#xff0c;我们传入url编码后的xml内容试一下 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE foo [<!EN…

社区店选址人流量标准:如何确保充足的顾客流量

在选择社区店的位置时&#xff0c;确保充足的顾客流量是至关重要的。 作为一名开鲜奶吧5年的创业者&#xff0c;我将分享一些关于社区店选址人流量标准的关键要点&#xff0c;帮助你找到最适合的店铺位置。 1、研究人口统计学数据 了解潜在顾客的人口特征是选址的基础。通过研…

Unity3D学习之Lua热更新解决方案(二)XLua

文章目录 1 XLua概述2 xLua导入和AB包相关准备3 C#调用Lua3.1 Lua解析器3.2 文件加载重定向3.3 Lua解析器管理器3.3.1 重定向AB包内的Lua3.3.2 获得_G大表 3.4 全局变量的获取3.5 全局函数的获取3.5.1 无参无返回3.5.2 有参有返回3.5.3 多返回值3.5.4 变长参数 3.6 List和Dicti…

C 嵌入式系统设计模式 18:临界区模式

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之四…

【AIGC】OpenAI推出王炸级模型sora,颠覆AI视频行业(2024)

对于OpenAI推出的Sora模型&#xff0c;我们可以进一步探讨其可能的技术细节、潜在应用以及对AI视频行业的影响。 点击以下任一云产品链接&#xff0c;跳转后登录&#xff0c;自动享有所有云产品优惠权益&#xff1a; 经过笔者亲测&#xff0c;强烈推荐腾讯云轻量应用服务器作…

前端打包部署(黑马学习笔记)

我们的前端工程开发好了&#xff0c;但是我们需要发布&#xff0c;那么如何发布呢&#xff1f;主要分为2步&#xff1a; 1.前端工程打包 2.通过nginx服务器发布前端工程 前端工程打包 接下来我们先来对前端工程进行打包 我们直接通过VS Code的NPM脚本中提供的build按钮来完…

Http基础之http协议、无状态协议、状态码、http报文、跨域-cors

Http基础 HTTP基础HTTP协议请求方法持久连接管线化 无状态协议使用Cookie状态管理 状态码1XX2XX OK200 OK204 NO Content206 Content-Range 3XX 重定向301302304307 4XX400401403404 5XX500503 HTTP报文请求报文响应报文通用首部字段Cache-ControlConnectionDate请求首部字段Ac…