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

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

标题:[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的,对于其他操作系统就不适用了。


完·~

未经作者同意禁止转载 

相关文章:

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

标题:[Linux] 文件系统 (1)—— 进程操作文件 个人主页水墨不写bug (图片来源于网络) 目录 一、进程与打开的文件 二、文件的系统调用与库函数的关系 1.系统调用open() 三、内存中的文件描述符表 四、缓冲区…...

RT-Thread 互斥量的概念

目录 概述 1 互斥量定义 1.1 概念介绍 1.2 线程优先级翻转问题 2 互斥量管理 2.1 结构体定义 2.2 函数接口介绍 2.2.1 rt_mutex_create函数 2.2.2 rt_mutex_delete 函数 2.2.3 初始化和脱离互斥量 概述 本文主要介绍互斥量的概念,实现原理。还介绍RT-Thre…...

6.计算机网络_UDP

UDP的主要特点: 无连接,发送数据之前不需要建立连接。不保证可靠交付。面向报文。应用层给UDP报文后,UDP并不会抽象为一个一个的字节,而是整个报文一起发送。没有拥塞控制。网络拥堵时,发送端并不会降低发送速率。可以…...

Windows应急响蓝安服面试

Windows应急响应 蓝队溯源流程 学习Windows应急首先要站在攻击者的角度去学习一些权限维持和权限提升的方法.,文章中的方法其实和内网攻防笔记有类似l红队教你怎么利用 蓝队教你怎么排查 攻防一体,应急响应排查这些项目就可以 端口/服务/进程/后门文件都是为了权限维持,得到s…...

PCL 点云配准-4PCS算法(粗配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 加载点云数据 2.1.2 执行4PCS粗配准 2.1.3 可视化源点云、目标点云和配准结果 2.2完整代码 三、实现效果 3.1原始点云 3.2配准后点云 PCL点云算法汇总及实战案例汇总的目录地址链接…...

12、论文阅读:利用生成对抗网络实现无监督深度图像增强

Towards Unsupervised Deep Image Enhancement With Generative Adversarial Network 摘要介绍相关工作传统图像增强基于学习的图像增强 论文中提出的方法动机和目标网络架构损失函数1) 质量损失2) 保真损失3)身份损失4)Total Loss 实验 摘要 提高图像的…...

Axure重要元件三——中继器表单制作

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 本节课:中继器表单制作 课程内容:利用中继器制作表单 应用场景:台账、表单 案例展示: 步骤一:建立一个背景区…...

DMAIC赋能智能家居:解锁未来生活新篇章!

从清晨自动拉开的窗帘,到夜晚自动调暗的灯光,每一处细节都透露着科技的温度与智慧的光芒。而在这场智能革命的浪潮中,DMAIC(定义Define、测量Measure、分析Analyze、改进Improve、控制Control)作为六西格玛管理的核心方…...

代码随想录算法训练营第二天| 209.长度最小的子数组 59.螺旋矩阵II 区间和 开发商购买土地

209. 长度最小的子数组 题目: 给定一个包含正整数的数组 nums 和一个正整数 target ,找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 ,并返回其长度。如果不存在符合条件的子数组,返回 0。 示例: 示例 1…...

mysql隐藏索引

1. 什么是隐藏索引? 在 MySQL 8 中,隐藏索引(Invisible Indexes)是指一种特殊类型的索引,它并不真正被删除,而是被标记为“不可见”。当索引被标记为不可见时,查询优化器在生成查询计划时将忽略…...

etcd入门到实战

概述:本文将介绍etcd特性、使用场景、基本原理以及Linux环境下的实战操作 入门 什么是etcd? etcd是一个分布式键值存储数据库 关键字解析: 键值存储:存储协议是 key—value 的形式,类似于redis分布式:…...

Build an Android project and get a `.apk` file on a Debian 11 command line

You can build an Android project and get a .apk file on a Debian 11 command line without using Android Studio. The process involves using the Android SDK command-line tools (sdkmanager, adb, and gradle). Here’s a step-by-step guide to building the ???…...

解读 Java 经典巨著《Effective Java》90条编程法则,第4条:通过私有构造器强化不可实例化的能力

文章目录 【前言】欢迎订阅【解读《Effective Java》】系列专栏java.lang.Math 类的设计经验总结 【前言】欢迎订阅【解读《Effective Java》】系列专栏 《Effective Java》是 Java 开发领域的经典著作,作者 Joshua Bloch 以丰富的经验和深入的知识,全面…...

Vivado HLS学习

视频链接: 6课:数据类型的转换_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1bt41187RW?spm_id_from333.788.videopod.episodes&vd_sourcea75d5585c5297210add71187236ec90b&p6 目录 1.数据类型的转换 2.自动类型转换 2.1隐式数据转换 2.2…...

一款AutoXJS现代化美观的日志模块AxpLogger

简介 Axp Logger是一款基于autox.js的现代化日志模块,具备窗口事件穿透、拖拽和缩放功能。 Axp Logger文档 特性现代化的UI设计支持点击穿透模式(不影响脚本运行)监听音量-键切换模式支持窗口操作模式窗口拖拽移动窗口自由缩放清空日志关闭日…...

成都睿明智科技有限公司共创抖音电商新篇章

在当今这个数字化浪潮汹涌的时代,抖音电商以其独特的魅力迅速崛起,成为众多商家竞相追逐的新蓝海。在这片充满机遇与挑战的领域中,成都睿明智科技有限公司凭借其专业的服务、创新的策略和敏锐的市场洞察力,成为了众多商家信赖的合…...

Spark的安装配置及集群搭建

Spark的本地安装配置&#xff1a; 我们用scala语言编写和操作spark&#xff0c;所以先要完成scala的环境配置 1、先完成Scala的环境搭建 下载Scala插件&#xff0c;创建一个Maven项目&#xff0c;导入Scala依赖和插件 scala依赖 <dependency><groupId>org.scal…...

网络编程基础-IO模型深入理解

一、IO的基本概念 什么是IO&#xff1f; I/O就是计算机内存与外部设备之间拷贝数据的过程 什么是网络IO&#xff1f; 网络IO是指在计算机网络环境中进行的输入和输出操作&#xff0c;涉及数据在网络设备之间的传输。 网络IO操作可以是发送请求、接收响应、下载文件、传输数…...

go 语言学习路线图(一)

1. Go语言简介 Go语言的历史背景和设计理念Go的优势&#xff1a;简洁、高效、并发支持强Go的应用场景&#xff1a;微服务、云计算、系统编程 2. 开发环境设置 安装Go语言开发环境 在Windows、macOS、Linux系统上的安装方法 配置环境变量&#xff1a;GOROOT 和 GOPATH验证安装…...

前端自动化部署,Netlify免费满足你

1 Netlify 介绍 为什么推荐 Netliy &#xff0c; 主要还是穷&#xff0c;Netlify 免费太香了 Netlify you优势100GB 内免费 &#xff0c;满足个人日常 需求&#xff0c;操作,兼容性绑定代码仓库&#xff0c;提交代码自动部署 支持 github , gitlab 等 大多常用代码仓库易操作只…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...