当前位置: 首页 > news >正文

文件fd

a.操作文件的本质 , 比如打开文件 , 关闭文件 , 并不是代码在打开和关闭 , 他的本质就是进程对文件的操作

b.总的来说 , 用户是没有权力直接向文件中写入数据的 , 因为OS并不相信任何人 , 他会给用户提供一套系统调用的方法来进行使用 , 达到简介写入文件的操作需求

1.系统调用的文件操作

首先我们来看第一个系统调用函数open

可以看到 , 这个open函数的返回值是int类型 , 然后后面还跟着一个int flags 标记位 , ok , 直接进入使用

接下来是结果

可以看到生成了一个log.txt文件 , 但是我们发现一个很奇怪的事情 , 前面的权限是一个非常奇怪的乱码

在Linux里面 , 当你想创建一个文件的时候 , 是必须要给他一个起始权限的 , 而在这里的open有两个

一个是下面这种带mode的 , 另一个是上面这种不带mode的 , 这两个有什么区别呢?

第一种的open是用来操作已经存在的文件的 , 而下面这种open是用来创建文件的 , 而后面的mode则是创建的起始权限

如果想让我们创建出来的文件的权限看起来比较正常一点 , 可以在后面加上想要的权限 , 比如

运行结果

可以看到几乎是按照我们想要的权限来进行创建了, 但是这里还是有一个比较奇怪的点 , 就是我想创建的不是"666"权限吗 , 为什么到这里就变成"664"权限了?

这是因为我们OS里面有一个默认创建文件时的umask掩码

当我们输入"666"的时候 , 这个时候他就会跟系统原本的掩码发生冲突 , 就会导致最后变成"664" , 想要修改也很简单 , 只需要修改umask变成0就行了(直接在代码的第一行里面加上umask(0)即可)

那这个时候 , 既有系统默认的掩码 , 也有自己想设置的掩码 , 那么该用谁的呢? 

答案是"就近原则"

a.标记位传参

我们可以看到 , open函数他后面带的一个参数是int flag , 但是我们传进去的缺是WRONLY和CREAT这些英文 , 这是为什么呢?

这就涉及到了一种传参的方式 ----->标记位传参

来看一下这段代码 , 我们就可以知道 , 所谓的标记为传参只不过是定义了一个宏定义 ,  然后通过或的方式来传参 , 就可以输出我们想要的内容

b.open函数的用法

中间的参数是三个 分别是O_WRONLY | O_CREAT | O_TRUNC ,

分别的意思就是 , 只写 , 如果没有就创建 , 每打开一次文件就刷新文件的内容

而下面的write函数则是把长度为这么多的message写进fd里面 , 这个就比较好理解

2.文件描述符fd的本质是什么?

我们知道了在系统调用中fd就是一个int类型 , 那么他到底是一个什么东西呢?

我们可以通过一段代码来探讨

下面是运行结果

可以看到 , 从fd1到fd4 , 他是3-6 

那为什么他不是从1-4呢?

原因很简单 , 在OS中 , 文件描述符里面,0代表的是标准输入,1代表的是标准输出,通常指的是屏幕输出,2代表的标准输出错误

知道了这些之后 , 我们再来看看fd他到底是什么东西.

在操作系统内部打开文件之后 , 就会有一个struct file 来管理这些文件 , 这些文件就用双链表来进行组织管理起来 , 这个时候OS就从对文件的管理进而转变成对双向链表的管理 , 然后他每个被打开的文件都有一个文件内核级的缓存 , 这个缓存就是OS来操作文件和磁盘之间的桥梁 , 当OS想改变文件内容的时候 , 就会通过缓存 , 然后保存到磁盘里面 ; 当想读取文件的时候 , 就会先读取磁盘 , 然后把内容映射到缓存 , 最后再输出到屏幕上面.

那我们都知道 , 一个进程可以同时管理多个文件, 对于进程来说 , 怎么分别辨认出每一个文件是哪个文件呢?

在图上面也画出来了, 在task_struct里面 , 他会有一个struct file指针数组 , 存放的是struct_file指针 , 里面的下标就是fd的值了

所以 , fd的本质就是内核的进程的文件映射关系的数组下标!!!

3.理解文件的读写操作

a.无论读写 , 都要让OS把文件内容读到相应的文件缓冲区

也就是说 , 不管如何去改 , 都要由OS从磁盘上读文件的内容放到文件缓冲区 , 然后修改 , 再刷新到磁盘上面 , 在读写操作的同时 , open正在

(1).创建file

(2).开辟文件缓冲区的空间,加载文件数据

(3).查进程的文件描述符表

(4).把file的地址填入对应的表的下标中

(5).返回下标

相关文章:

  • 苏剑林“闭门造车”之多模态思路浅谈思考
  • PageHelper分页插件
  • C语言题目:链表数据求和操作
  • 【系列教程】Python第三课:用前两课知识解决实际问题
  • “mysqld --initialize --console ”执行不成功情况总结和解决措施
  • vue3-04vue3中ref函数( 定义一个响应式的数据)
  • 设计模式14:职责链模式
  • 普通报表入门
  • 使用html css js 开发一个 教育机构前端静态网站模板
  • Show 『Picture Add + Crosee Line ROI
  • 【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析④】
  • 《StyleID:一种无训练的方法将大规模扩散模型适配于风格迁移》
  • Mistral Saba:为中东和南亚量身打造的AI模型
  • npu 瑞芯微rk系列,rknn模型转换以及npu使用
  • ES8字符串填充用法总结:padStart(),padEnd(),rest剩余参数的用法{name,...obj},扩展运算符的用法,正则表达式命名捕获组
  • 聚焦地灾防治,助力城市地质安全风险防控
  • 基于STM32的智能交通信号控制系统
  • Windows环境打印文档的同时自动生成PDF副本的方法
  • SpringBoot中自动装配机制的原理
  • Pytorch实现论文之一种基于扰动卷积层和梯度归一化的生成对抗网络
  • 体坛联播|C罗儿子完成国家队首秀,德约结束与穆雷合作
  • 杭州钱塘区3宗涉宅用地均以底价成交,共计成交金额25.73亿元
  • 中拉论坛部长级会议为何悬挂海地和圣卢西亚的国旗?外交部回应
  • 中国创面修复学科发起者之一陆树良教授病逝,享年64岁
  • 美国拟向阿联酋和沙特AI公司出口数十万枚芯片
  • 哈马斯表示已释放一名美以双重国籍被扣押人员