【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件

目录

​编辑

前言

系统调用

open

参数flags

 参数mode

write

追加方式

read

close

 文件描述符

打开多个文件并观察其文件描述符

C语言文件操作

理解一切皆文件 

理解open操作


前言

各类语言的文件操作其实是对系统调用的封装

我们经常说,创建一个文件,或者打开一个文件,其实并不是我们用户本身创建,而是进程创建文件。文件是存储在磁盘上的,是硬件,像文件写入其实就是向硬件写入,而我们用户这一角色是没有权力直接写入的,操作系统(OS)是硬件的管理者,必须要通过OS写入;

但是,OS不相信任何人,只是提供了系统调用接口对外,想访问文件,就需要使用系统调用;而C/C++..语言都提供了这些系统调用的封装,为何要封装呢?跨平台性。

系统调用

open

打开一个文件,返回一个文件描述符,可以以flags形式打开文件

//2号手册 是系统调用(System Calls)  查找系统调用里面的open函数
man 2 open   

pathname:表示文件的路径名,也可以是一个文件名;如果没有路径名,默认在当前文件下;
flags:表示打开文件的方式选项,参见选项有: 

  • O_WRONLY:只写打开
  • O_CREAT:文件不存在时创建文件
  • O_RDONLY:只读打开
  • O_RDWR:读写方打开
  • O_APPEND:追加方式打开
  • O_TRUNC:清空文件,重新写入

mode:如果这个文件不存在,那么以写的方式打开的时候就会创建这个文件,在创建文件的时候需要给这个文件设定权限(使用八进制数)(会被umask影响);

        如果这个文件存在的话,那么就不用传第三个参数了,因为文件的权限已经确定了

参数flags

open函数定义中,flags是以整形定义的,有32比特位,满足参数个数不固定的情况,以二进制形式传参;

        实际上是一个32位二进制的位图,位图(Bitmap)是一种基于位操作的数据结构,用于表示一组元素的集合信息。位图中的每个二进制位都表示着某个元素是否在集合中。

        比如宏O_WRONLY假设表示的是2即10(二进制),O_CREAT表示4,即100(二进制)。那么O_WDONLY|O_CREAT=110(二进制)。在open函数内部就会有相应的机制监测flags的二进制位哪些是1,再分别对应其代表的功能

 参数mode

表示一个四位八进制的数,取后三位来表示各个角色的权限;

例:0666,取666用二进制表示的就是110 110 110分别对应文件的拥有者、所属组、其他人的(other)权限。

如果当文件不存在时,就要设置该参数,不然就会出现权限处乱码

当新建一个文件时,一定要加上mode参数,来设置权限

 

umask默认为002,也就是过滤掉了“其他人”的w权限,所以得到的最终文件权限编码是664。 

文件权限和权限掩码的关系:文件权限& (~umask权限掩码)

write

用于向文件中写入数据。通过指定文件描述符、数据来源的缓冲区地址和要写入的字节数;可以将数据写入到文件中。如果写入失败则返回-1,否则返回写入的字节数;

  • fd表示的是文件标识符
  • buf表示的是数据的地址;
    • 对于系统调用来说,它并不在意写入的数据是什么类型的,它接收到的数据都是二进制的数字,然后按照字节为单位写入。
  • count表示的是字节数
  • 返回值类型: ssize_t 类型表示有符号整型,输出格式为%ud.

 

追加方式

以追加方式写入,只需要在open(...)第二个参数中 把O_TRUNC换成O_APPEND

read

用于从文件中读取数据。通过指定文件描述符、缓冲区地址和读取的字节数;

可以将文件中的数据读取到缓冲区中。

读取成功返回读取的字节数,否则返回-1.

int fd:打开文件时返回的文件描述符。
void* buf:从文件中读取的数据放在这个数组中,同样系统不管文件中的数据类型是什么,都是按字节放入这个数组中。
size_t count:要读取的字节个数。
ssize_t:读取了多少个返回多少。 

使用只读方式打开(目标文件已经存在,open(...)中mode参数可以不用加入设置);

将读取的内容放在ch_arr数组中。 

close

用于关闭一个文件描述符,释放系统资源。(也就是令struct file* fd_array[]对应下标fd指向空。)

在文件操作完成后,应该及时关闭文件描述符,以防资源泄漏。

关闭成功返回0,否则返回-1.

 文件描述符

 操作系统要管理文件,必定要让文件先加载到内存,然后先描述,再组织。内核中要有描述对应文件的结构体——也就是struct file

        struct file中最核心的数据可以分为3大类,属性,方法集,缓冲区。而文件描述符fd就存在属性当中。

        文件是由进程发起创建的,而一个进程实际上是一个PCB(task_struct),里面有一个结构体指针struct file_struct* files,指向了一个结构体。这个结构体中又有一个指针数组struct file* fd_array[N]该指针数组存放了指向进程所打开文件的结构体下标,也就是文件描述符fd;

  • 内核会返回一个小的非负整数。这个非负整数就叫做描述符,也叫文件描述符。文件描述符是用于唯一标识文件的号码。
  • 进程实际上并不记录文件本身,而只需要记录一个为一个文件ID。所有被打开的文件的信息都被集中在一起被内核管理,内核向进程提供文件的接口。

打开多个文件并观察其文件描述符

创建的每一个进程开始的时候都有三个打开的文件:标准输入流(fd=0),标准输出流(fd=1),标准错误流(fd=2)。

 这三个文件分别对应的硬件设备是键盘、显示器、显示器。

而这三个都是默认自动打开的

 

当进程打开文件时,会在struct file*数组中找到当前没有被使用的最小的下标,作为新的文件标识符。

如果在打开文件之前,把这个三个文件流关闭,那么就会自动分配到当前的最小下标。

C语言文件操作

C语言文件操作默认打开三个输入输出流,分别是stdin,stdout,stderr。 

 之前提到过,不同语言的文件操作不过是对系统调用的封装,这里发现C语言的返回值和系统调用open..返回值不一样,我们大胆猜测FILE是一种封装

 打印输入输出流

 

 可以发现,FILE结构体中是有文件描述符的。

文件描述符fd的分别规则是:从小到大,按顺序查找,将没有被占用的数组下标作为被打开文件的文件描述符fd值。

理解一切皆文件 

这个文件可以理解成结构体

  • 每一个硬件,操作系统都会维护一个struct file类型的结构体,硬件的各种信息都在这个结构体中,并且还有对应读写函数指针(对硬件的操作主要就是读写)。
  • 每个硬件的具体读写函数的实现方式都在驱动层中,使用到相应的硬件时,操作系统会通过维护的结构体中的函数指针调用相应的读写函数。

 

  •  站在操作系统的角度来看下层,无论驱动层和硬件层中有什么,在它看来都是struct file结构体,都是通过维护这个结构体来控制各种硬件。
  • 站在操作系统的角度来看上层,无论用户层以及系统调用有什么,在它看来都是一个个进程,都是一个个的task_struct结构体,都是通过维护这个结构体来调度各个进程的。
  • 真正的文件在操作系统中的体现也是结构体,操作系统维护的同样是被打开文件的结构体而不是文件本身。

理解open操作

  • 创建struct file(包括fd)
  • 开辟文件缓存区,加载文件中的数据(延后)
  • 查进程的文件描述符表(fd_array数组)
  • 将file的内存地址填入到fd_array[fd]中
  • 返回fd. 

 

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

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

相关文章

力扣第三十七题——解数独

内容介绍 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独…

CVE-2024-39700 (CVSS 9.9):JupyterLab 模板中存在严重漏洞

在广泛使用的 JupyterLab 扩展模板中发现了一个严重漏洞,编号为CVE-2024-39700 。此漏洞可能使攻击者能够在受影响的系统上远程执行代码,从而可能导致大范围入侵和数据泄露。 该漏洞源于在扩展创建过程中选择“测试”选项时自动生成“update-integratio…

VIM基础配置

1. CTAGS配置 下载 上传虚拟机,解压,进入目录 tar -xzvf ctags-5.8.tar.gz cd ctags-5.8/编译 ./configure sudo make sudo make install查看是否安装成功 ctags --version打印如下 2. 使用Vundle 下载 git clone https://github.com/VundleVim/Vund…

Linux并发程序设计(3):守护进程

目录 前言 一、介绍 1.1 概念 1.2 特点 1.3 举例 二、系统编程 2.1 setsid函数 2.2 getpid函数 2.3 getsid函数 2.4 getpgid函数 2.5 chdir函数 三、代码例程 3.1 使子进程在后台运行 3.2 使子进程脱离原终端 3.3 更换目录,并设定权限(非…

基于STM32通过云平台实现智慧大棚【手机远程查看温湿度】【报警】

文章目录 一、成果演示二、所用到的模块三、实现的功能四、接线说明五、WIFI模块配置步骤5.1云平台介绍5.2云平台使用5.3使用USB转TTL测试联通云平台 六、STM32代码编写七、手机上查看数据6.1下载软件(仅限安卓手机)6.2操作 一、成果演示 STM32通过物联网…

String、StringBuffer和StringBuilder

一、String类 1. String类的理解 2. String类结构 1. String类实现了Serializable接口,说明String对象可以串行化,即可以在网络上传输 2. String类实现了Comparable接口,说明String对象可以比较 String底层是一个字符数组,这个数组里存的是字符串的内容 例如:…

005 仿muduo实现高性能服务器组件_通信连接管理

​🌈个人主页:Fan_558 🔥 系列专栏:仿muduo 📒代码仓库: 项目代码 🌹关注我💪🏻带你学更多知识 文章目录 前言Channel模块设计原因整体设计代码如下 Connection模块设计原…

Florence2:Advancing a unified representation for a variety of vision tasks

Florence-2模型:开启统一视觉基础模型的新篇章_florence -2-CSDN博客文章浏览阅读1.1k次,点赞108次,收藏109次。Florence-2是由微软Azure AI团队开发的一款多功能、统一的视觉模型。它通过统一的提示处理不同的视觉任务,表现出色且优于许多大型模型。Florence-2的设计理念是…

用Postman Flows打造你的专属API:外部公开,轻松上手!

引言 Postman Flows 是一个使用 GUI 进行无代码 API 调用流程创建的服务。这篇文章我尝试使用 Flows 来构建将 Momento Topic 中的数据保存到 TiDB 的保存 API,因此想分享一些使用过程中的技巧等。 实现内容 将从 Momento Topics 配发的 JSON 数据保存到 TiDB 中。…

C++ 栈( stack )学习

目录 1.栈 2.模拟栈 1.1.入栈( push ) 1.2.出栈( pop ) 1.3.获取栈顶元素( top ) 3.直接使用栈( stack ) 3.1.导入头文件并创建栈 3.2.栈的操作 3.2.1.入栈( push ) 3.2.2.出栈( pop ) 3.2.3.获取栈顶元素( top ) 3.2.4.获取栈中元素个数( size ) 3.2.5.判断栈是否…

代码随想录算法训练营day8 | 344.反转字符串、541.反转字符串 II、卡码网:54.替换数字

文章目录 344.反转字符串思路 541.反转字符串 II思路 卡码网:54.替换数字思路复习:字符串 vs 数组 总结 今天是字符串专题的第一天,主要是一些基础的题目 344.反转字符串 建议: 本题是字符串基础题目,就是考察 revers…

docker挂载部署reids6.2.1

1.拉取镜像 docker pull redis:6.2.12.创建挂在目录(根据自己要求修改具体目录) mkdir -p /home/admin/redis/{data,conf}3.在/home/admin/redis/conf目录下创建redis.conf文件 cd /home/admin/redis/conf touch redis.conf4.复制下面文本到redis.conf…

浅析JWT原理及牛客出现过的相关面试题

原文链接:https://kixuan.github.io/posts/f568/ 对jwt总是一知半解,而且项目打算写个关于JWT登录的点,所以总结关于JWT的知识及网上面试考察过的点 参考资料: Cookie、Session、Token、JWT_通俗地讲就是验证当前用户的身份,证明-…

不断把别人“装”进我们的灵魂口袋

嘿,朋友们!今天我们来聊聊一种超酷的能量——本色示人。这不是什么秘密武器,但它比任何超能力都来得实在。 第一部分:本色示人,能量界的“超级赛亚人” 1.1 坦诚的超能力 想象一下,如果你的内心强大到可以…

Window部署Ollama+Qwen2.0+Open-WebUI

文章目录 Windows下安装Docker安装Docker检查是否安装成功, 出现版本即为安装成功安装Ollama启动 Ollama 并拉取模型(选做) 修改默认地址和端口(选做) Ollama 进行跨域配置安装open-webui Windows下安装Docker 准备条件 开启Hyper-V,在“启用或关闭Windows功能”里…

C语言 #指针数组 #数组指针 #数组参数、指针参数

文章目录 前言 一、指针数组 1、概念: 2、指针数组有什么用呢? 二、数组指针 1、数组指针的定义 2、数组名与 &数组名 的区别 3、数组指针如何初始化? 4、数组指针的用法 三、根据代码区分 指针数组 和 数组指针 四、数组参数、指针参数 …

Shell编程之正则表达式与文本三剑客

目录 一、正则表达式 1.引言--什么是正则表达式 1.1正则表达式的功能 2.基础正则表达式(BRE) 2.1特殊字符 2.2定位符 2.3非打印字符 3.扩展正则表达式(ERE) 4.元字符操作的案列 二、命令小工具 1.cut:列截取工具 2.sort排序 …

【Android】使用ViewPager2与TabLayout实现顶部导航栏+页面切换

【Android】使用ViewPager2与TabLayout实现顶部导航栏+页面切换 TabLayout与ViewPager2概述 TabLayout TabLayout 是 Android 支持库中的一个组件,它是 Design 支持库的一部分。TabLayout 提供了一个水平的标签页界面,允许用户在不同的视图…

CogVideo 实测,智谱「清影」AI视频生成,全民免费,连 API 都开放了!

不得不说,AI 视频生成界最近非常火热~ 前有快手「可灵」开放内测,一下子带火了老照片修复,全网刷屏: 怕是你还没拿到内测资格,被称为 “国货之光” 的「可灵」就结束了免费无限量模式。每天只有66点的免费额度&#x…

鸿蒙(API 12 Beta2版)【创建NDK工程】

创建NDK工程 下面通过DevEco Studio的NDK工程模板,来演示如何创建一个NDK工程。 说明 不同DevEco Studio版本的向导界面、模板默认参数等会有所不同,请根据实际工程需要,创建工程或修改工程参数。 通过如下两种方式,打开工程创…