[Linux] 逐层深入理解文件系统 (1)—— 进程操作文件

news2024/12/23 20:42:48

标题:[Linux] 文件系统 (1)—— 进程操作文件

个人主页@水墨不写bug

        (图片来源于网络)

目录

 一、进程与打开的文件

 二、文件的系统调用与库函数的关系

1.系统调用open()        

三、内存中的文件描述符表

四、缓冲区的理解 

五、俯瞰IO 


正文开始:

 一、进程与打开的文件

        C/C++都提供了对文件进行操作的函数接口,想要对文件操作:无论是往文件中写入,还是从文件中读出,都需要满足一个前提条件:文件被打开。

        文件被打开,意味着文件被从磁盘中加载到内存中。进程是我们写的C/C++指令编译行成的运行起来的程序,本质是我们想要完成想要某一个任务。于是,我们不得不考虑加载到内存中的文件与进程之间的关系。

        文件是在磁盘中存储的,磁盘是一个硬件外设,对文件操作本质就是对磁盘这个硬件操作。但是用户没有权利直接向硬件写入。想要完成对硬件操作,需要 软硬件资源的管理者——操作系统的帮助。但是操作系统不相信如何用户,于是需要用操作系统提供的安全的访问操作系统数据的方式——系统调用。

        于是,我们通过分析可以推测——我们使用的

        fopen/fwrite/fread/fprintf/scanf/printf/cin/cout

等一系列的C/C++的文件操作的库函数,本质都是对系统调用的封装!

        这样一来,为了搞清楚封装的细节,我们需要先知道如何使用系统调用。

 二、文件的系统调用与库函数的关系

1.系统调用open()        

open()函数原型:

 

参数:

        pathname:想要打开的文件的名称;

        flags:打开的文件的方式选项,常见的选项有:

O_WRONLY: 以写的方式打开文件。

O_CREAT:     如果不存在就创建文件。

O_TRUNC:    每一次打开清空文件内容。

O_APPEND:打开文件之后不清空文件内容,而在后面追加。

        mode:如果成功创建了文件,文件被创建出来的默认权限设置。

返回值:

        一个整数int,被称为文件描述符(file descriptor)。

         其实,C语言的fopen函数在的不同打开方式,都对应一种flags的组合。C语言对文件打开方式有"w" "r"等等的区分,由于C语言fopen函数底层调用的还是open系统调用,所以自然会发现这样的对应关系:

         这两个调用本质都是对第一个系统调用函数open的调用,只不过第二种C语言式的函数调用对第一种系统调用进行了封装,在函数内部增加了语言级别的缓冲区等的操作,并且对返回值也进行了封装,把int类型的返回值封装成了FILE结构体指针类型的返回值。

        为什么C语言要这样做呢?别急,接下来我们对文件有了深入的理解认识之后,你就会体会到C语言的良苦用心了。


三、内存中的文件描述符表

        在上面的理解中,我们发现  系统调用open()函数  的返回值是一个整形int,对应的,我们发现  系统调用close()  函数也是通过一个int整数来关闭文件的,这非常令人费解,为什么仅仅凭借一个整数就可以操作整个文件的开关?

        在操作系统中,运行有成百上千的进程,每时每刻都有进程的创建,消亡。每一个进程都可以打开文件,并且一个进程可以打开不止一个文件!这就意味着操作系统必须要有一个高效的管理打卡的文件的方式,这个方式就是:

先描述,再组织!

         在内存中,不止有进程的PCB(task_struct),还有描述文件的数据结构:文件描述符表

        我们可以暂时把文件描述符表抽象理解成一个数组,这个数组存储文件的数据。磁盘中的文件被加载到内存中,就是通过这个数组来维护的。

        而open的返回值,就是打开的文件在这个数组中对应的下标!!

 

        如上图,一个个的文件被加载到内存中后,会被存储在files_struct这个结构体数组中,这个数组就是文件描述符表!

        不同的文件存储在不同下标位置:

 

         于是每一个文件就有了一个对应的下标:fd;这也就解释了为什么操作系统为什么可以拿着一个整数来对文件进行操作:因为操作系统可以通过一个整数下标来标识一个文件。

 


         当我们一次性打开并关闭多个文件,重复几次,会发现fd的分配规则:

                1)fd的0,1,2被默认提前分配为标准输入(键盘),标准输出(显示器),标准错误(显示器)。(C语言的stdin,stdout,stderr本质也是对这三个文件的封装)

               2)fd的分配机制是按照从小到大的顺序分配fd下标。

 


四、缓冲区的理解 

        语言有语言的缓冲区,系统有系统的缓冲区,这两个缓冲区存在的目的都是为了提高IO效率:

        1)因为访问外设与CPU的速度相比非常慢,所以系统缓冲区存在的意义就是尽量减少对外设的访问,当向缓冲区写入一定量的数据之后,操作系统会一次性把数据刷新到磁盘中。 

                

         2)系统调用的使用成本比库函数要高的多,因为操作系统太忙了,每一次调用系统调用都是请求操作系统配合用户一次,频繁调用会导致效率损失。所以语言缓从区存在的意义就是尽量少调用系统调用,当我们向语言级缓冲区写入一定的数据之后,C语言函数会一次性把数据刷新到系统级缓冲区。

        


五、俯瞰IO 

        这时,我们整体俯瞰io的过程:

        当我们打开一个文件,操作系统会调用open:

        1)创建file结构体;

        2)开辟文件缓冲区内容,加载问价数据(延后)

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

        4)file地址,填入对应的表的下标中

        5)返回下标

        当我们调用fopen库函数,会在上面操作的基础上创建语言级缓冲区等操作,本质是为了改善用户体验,提高效率。

         为什么C语言要封装系统调用?

        1)提高效率,改善用户体验

        2)C语言有多个不同的在不同的平台上实现的版本,具有跨平台性。但是我们所讲的系统调用,仅仅是Linux的,对于其他操作系统就不适用了。


完·~

未经作者同意禁止转载 

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

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

相关文章

【Java SE 】类和对象详解

🔥博客主页🔥:【 坊钰_CSDN博客 】 欢迎各位点赞👍评论✍收藏⭐ 目录 1, 面向对象认识 1.1 什么时面向对象 1.2 面向对象和面向过程 1.2.1 一个例子理解对象和过程 1. 对于电脑来说 2. 对于我们人来说 2. 类的定…

还在为调用大模型API接口返回数据的处理问题烦恼???来看看这篇文章,解决你的烦恼!!!

大家好!我是学徒小z,今天给大家分享一下我做项目过程中遇到的一个问题。 文章目录 问题大模型接口解决方案流式返回和回调函数另一个问题1. 使用web组件2. 使用第三方库 问题 不知道大家有没有遇到这样一个问题。在调用大模型接口的时,返回…

Lnmp(mysql分离)(nginx 1.13.6+mysql5.5+php5.3)环境一键搭建

Lnmp(mysql分离)(nginx 1.13.6mysql5.5php5.3)环境一键搭建 如果对运维课程感兴趣,可以在b站上、csdn或微信视频号 上搜索我的账号: 运维实战课程,可以关注我,学习更多免费的运维实…

深度学习之残差网络ResNet

文章目录 1. 残差网络定义2. 数学基础函数类3. 残差块4.ResNet模型5.训练模型6.小结 1. 残差网络定义 随着我们设计的网络越来越深,深刻理解“新添加的层如何提升神经网络的性能”变得至关重要。更重要的是设计网络的能力。在这种网络中,添加层会使得网…

单例模式:为何继承无法保证子类的单例特性

这里写目录标题 一、引言二、背景描述三、单例模式的规范边界全局访问点与静态工厂方法代码示例与注意事项 四、单例实现继承遇到的问题五、结论与替代方案结论替代方案特殊的想法🌸🌸源码阶段验证编译阶段验证运行阶段验证总结 一、引言 在软件设计中&a…

实时语音转文字(基于NAudio+Whisper+VOSP+Websocket)

今天花了大半天时间研究一个实时语音转文字的程序,目的还包括能够唤醒服务,并把命令提供给第三方。 由于这方面的材料已经很多,我就只把过程中遇到的和解决方案简单说下。源代码开源在AudioWhisper: 实时语音转文字(基于NAudioWhisperVOSPWe…

基于SSM的个性化商铺系统【附源码】

基于SSM的个性化商铺系统 效果如下: 用户登录界面 app首页界面 商品信息界面 店铺信息界面 用户功能界面 我的订单界面 后台登录界面 管理员功能界面 用户管理界面 商家管理界面 店铺信息管理界面 商家功能界面 个人中心界面 研究背景 研究背景 科学技术日新月异…

Leetcode 每日温度

class Solution {public int[] dailyTemperatures(int[] temperatures) {int n temperatures.length;Stack<Integer> stack new Stack<>();//默认将数组中的所有元素初始化为 0int[] results new int[n];for(int i 0; i < n; i) {while(!stack.isEmpty() &a…

leaflet前端JS实现高德地图POI兴趣点批量分类下载(附源码下载)

前言 leaflet 入门开发系列环境知识点了解&#xff1a; leaflet api文档介绍&#xff0c;详细介绍 leaflet 每个类的函数以及属性等等leaflet 在线例子leaflet 插件&#xff0c;leaflet 的插件库&#xff0c;非常有用 内容概览 leaflet前端JS实现高德地图POI兴趣点批量分类下载…

小猿口算炸鱼脚本

目录 写在前面&#xff1a; 一、关于小猿口算&#xff1a; 二、代码逻辑 1.数字识别 2.答题部分 三、代码分享&#xff1a; 补充&#xff1a;软件包下载 写在前面&#xff1a; 最近小猿口算已经被不少大学生攻占&#xff0c;小学生直呼有挂。原本是以为大学生都打着本…

【Python爬虫】看电影还在用VIP?一个python代码让你实现电影自由!附源码

今日主题 如何用Python解析vip电影。 什么是vip电影&#xff1f; 这些vip电影啊&#xff0c;想要观看的话&#xff0c;必须充值会员&#xff0c;否则没法看。 比如这个&#xff1a; 这些vip电影解析后呢&#xff1f; 不需要会员&#xff0c;不需要登录&#xff0c;可以直接…

Java-类与对象

一、面向对象 在了解类与对象前&#xff0c;我们需要先知道"面向对象"这个词的概念&#xff1a; 在Java语言中&#xff0c;我们的主要思想就是"面向对象"&#xff0c;而在之前我们所学习的C语言中大部分时候的思想是"面向过程"。 那么什么是&…

MySQL-10.DML-添加数据insert

一.DML(INSERT) -- DDL&#xff1a;数据操作语言 -- DML&#xff1a;插入数据 - insert -- 1.为tb_emp表的username&#xff0c;name&#xff0c;gender字段插入值 insert into tb_emp (username,name,gender) values (wuji,无忌,1); -- 这样会报错&#xff0c;因为create_ti…

DS堆的实际应用(10)

文章目录 前言一、堆排序建堆排序 二、TopK问题原理实战创建一个有一万个数的文件读取文件并将前k个数据创建小堆用剩余的N-K个元素依次与堆顶元素来比较将前k个数据打印出来并关闭文件 测试 三、堆的相关习题总结 前言 学完了堆这个数据结构的概念和特性后&#xff0c;我们来看…

限时设计ui

ctrl-------放大缩小 空格-----画面移动 alt------复制 页面<画板<图层 添加交互事件 原型 点击蓝色的圆&#xff0c;从1跳转到2 点击绿色的圆&#xff0c;从2跳转到1

基于SSM+Vue+MySQL的健身房管理系统

系统展示 系统背景 随着人们生活水平的提高和健康意识的增强&#xff0c;越来越多的人选择去健身房锻炼。传统的健身房管理方式往往依赖于纸质记录和人工操作&#xff0c;这种方式不仅效率低下&#xff0c;而且容易出错。为了提高健身房的管理效率和服务质量&#xff0c;开发一…

python项目实战——下载美女图片

python项目实战——下载美女图片 文章目录 python项目实战——下载美女图片完整代码思路整理实现过程使用xpath语法找图片的链接检查链接是否正确下载图片创建文件夹获取一组图片的链接获取页数 获取目录页的链接 完善代码注意事项 完整代码 import requests import re import…

图文检索综述(2):Deep Multimodal Data Fusion

Deep Multimodal Data Fusion 摘要1 引言2 基于编码器-解码器融合2.1 数据级别融合2.2 分层特征融合2.3 决策级别融合 3 基于注意力融合3.1 模态内的自注意力3.2 模态间的交叉注意力3.3 基于transformer的方法 4 基于图神经网络融合4.1 单个模态的表示学习4.2 融合数据的表示学…

【数据结构】宜宾大学-计院-实验三

线性表的应用——实现两多项式的相加 课前准备&#xff1a;实验学时&#xff1a;2实验目的&#xff1a;实验内容&#xff1a;实验结果&#xff1a;实验报告:&#xff08;及时撰写实验报告&#xff09;实验测试结果&#xff1a;代码实现&#xff1a;&#xff08;C/C&#xff09;…

Java 小游戏《超级马里奥》

文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目&#xff0c;并将本游戏需要用到的图片素材 image…