文件与进程

server/2024/9/23 11:18:17/

理解文件:

操作文件的本质是进程在操作文件!这是进程和文件的关系!

如何理解文件?

文件在未打开之前是存在磁盘中的,而磁盘是在外设上的,也就是硬件上的,所以向文件中写入,本质上就是在朝硬件中写入,但是用户并没有权力直接在硬件上进行写入操作,所以必须通过操作系统进行写入,所以使用fopen、fwr、fprintf等等,其实本质上都是一个操作系统的调用函数,是C语言库对操作系统提供的系统调用函数的一种封装,同时C/C++等其他语言访问文件的方式有些不一样!

文件操作:

open:打开文件

  • 第一个参数是文件名或者文件路径,只有文件名则是表示打开的文件在当前的路劲下
  • 第二个参数是表示这么创建这个文件,表示一个整数,能使用很多标记为

标记位的使用:

标记位是 以写方式打开,如果没有则创建,如果fd获取的标记为是小于0则表示文件打开失败!

创建了这个文件,而这个文件创建出来的权限不对劲!在Linux中,如果创建文件,就要设置这个文件的初始权限,所以这就需要第三个参数来赋予文件的权限!同时权限也是一个整数

0666表示的就是一个文件的读写权限

不过为什么这个文件的权限是664而我们赋予的是666,这是系统中存在的一个权限掩码,这是系统将权限掩码和我们赋予的权限进行了位运算,这个权限掩码是可以进行更改的!

使用umask函数将权限掩码变成0,这样就可以把文件的权限设置成我们想要的权限了!注意权限掩码默认是002为什么open的第二个参数是整数,那为什么我们写的全是字符?

一个整数是由32位比特位写的 ,所以使用比特位来进行标志位的传递,这是操作系统对很多系统调用接口的一种常见方式!而我们在第二个参数上写的字符,其实是以比特位来设计的一种宏!

 关闭文件:
 

 

写入文件:

 

文件描述符 fd:

是以上文件函数的 第一个参数 ,同时也是打开文件失败的返回值!并不是从0、1、2开始进行返回值的,而是从3开始,而0、1、2分别是标准输入、标准输出、标准错误

0、1、2是系统开启后默认打开的,同样也可以被使用:

操作系统要为被打开的文件进行管理,所以每次打开一个文件 操作系统就会形成一个关于这个文件的内核数据结构struct file ,这个内核数据结构会拥有关于该文件的属性,例如文件的打开方式。

而对于文件的管理就是对struct file 的管理,而一群struct file 结构体 会进行双链表链接,同时每一个文件都会拥有操作系统为文件申请的一个内存,也就是文件按内核级的缓存区

所以最后,文件的属性是用来进行struct file 的初始化,而文件的内容则是存放在文件内核级缓存区中,每次的修改的内容都会在缓存区中存放,并由缓存区冲刷到文件所在的磁盘中进行修改,而读取文件内容则是文件将内容拷贝到缓存区中

所以无论读写都必须让操作系统把文件的内容读取到缓存区当中!所以对于文件的修改是内核级的,而不是磁盘级的

而对于打开文件的本质是打开进程,进程可以打开多个文件,所以进程对文件的关系是一对多,那进程如何找到它自己打开的文件呢

在进程task_strucrt 的属性中具有一个struct files_struct *file 的数据数据结构,正是使用了这个结构体,才让进程和文件建立了关系

struct files_struct *file 的内部存在一个数组,且是一个指针数组,这个指针数组内部的指针指向的就是文件,同时数组的0、1、2下标存储的是标准输入、标准输出、标准错误

同时文件的地址一一被struct files_struct *file内部的指针指向,并存放在了这个数组的内部,而这个数组的下标最终会被拿取,变成 文件描述符,所以fd的本质就是这个数组的下标,通过这个下标来获取文件的信息和内容 

open是在创建file 和开辟文件缓存区的空间,加载文件数据,进行查找进程的文件缓存区的表,把file的地址填入对应的表内,最后返回数组下标

 那为什么fd 0、1、2会默认打开?

因为0、1、2是硬件!而对于Linux中一切皆文件!所以硬件也是文件!

而对于一切皆文件如何理解?

对于每一个设备而言,都具有名字、类别、厂商、操作方法等属性

因此每一个操作系统都可以被一个结构体所描述:

同时每一个文件 的 struct file 内部都具有相对应的读写指针,而每一个硬件设备的驱动内都有读写操作方法实现,虽然每一个硬件设备的读写操作实现方法都是不一样的,但是可以设置成一样类型的,所以文件中的struct file内部的读写指针可以一一指向和对应硬件驱动上的读写操作方法!

而对与每一个被打开的文件来说,它的读、写指针是struct file 内部的一块新的属性,也是每一个被打开文件的操作底层!

所以,只需要看struct file 内部的读写指针指向那个硬件的读写方法,就表示这个文件访问了这个硬件!所以这就是一切皆文件!在操作系统内部,系统在访问文件的时候只认文件描述符fd!

而对于C语言C++的文件操控函数,例如fopen、fcolose等 为什么需要使用FLIE作为类型指针,这是因为FILE是一个C语言提供的结构体,而在这个结构体的内部一定是要封装fd 的! 所以所有C语言上的文件操作函数,本质底层都是系统调用的封装!

C语言为什么要这样做?

C语言可以使用系统调用,也可也使用语言层面上提供的文件方法,这主要是因为操作系统的不同,系统调用的函数可能不一样,而C语言是一个能够跨平台的语言,所以可以直接使用C语言的方法。


http://www.ppmy.cn/server/98303.html

相关文章

前端获取视频文件宽高信息和视频时长

安装 yarn add video-metadata-thumbnails | npm install video-metadata-thumbnails引入依赖包 import { getMetadata } from video-metadata-thumbnails使用 if (file.name.includes(mp4)) {if (file) {try {console.log(file)// 获取视频的元数据const metadata await …

Cesium初探-相机

在 Cesium 中,相机(Camera)是一个非常重要的概念,它代表了用户观察 3D 场景的视角。相机不仅决定了用户看到的内容,还定义了观察的角度、距离和方向。理解 Cesium 中的相机是如何工作的对于创建有效的 3D 地图和地球应…

【ACM出版,EI稳定检索】第四届信号处理与通信技术国际学术会议(SPCT 2024)

第四届信号处理与通信技术国际学术会议(SPCT 2024) 2024 4th International Conference on Signal Processing and Communication Technology 重要信息 大会官网:www.icspct.com 大会时间:2024年12月27-29日 大会地点&#xff1a…

流媒体服务器XMedia插件服务安装使用

XMedia是AMS流媒体服务器的一个插件服务,可以扩展支持 FLV 、GB28181上传、WEBRTC、SRT协议上传,增强了服务器的功能 一、服务插件安装 资源下载 XMedia-CentOS7-x86-64-20240710-212007 把安装包放入LINUX服务器,执行如下命令,如果未安装u…

【YOLOv8系列】YOLOv8数据集制作过程;YOLOv8分类数据集制作;深度学习算法数据集制作;数据集处理,丰富数据集数据,增强数据集的多样性;

我们知道,对于深度学习算法,要想训练出一个效果不错的模型,一个好的训练数据集是非常重要的;本文记录一下我制作YOLOv8分类算法数据集的过程;当然也适用于YOLOv8的其他算法,甚至其他深度学习算法也是可以使用的。 在计算机视觉任务中,数据的多样性是提高模型性能的关键…

Redis01- 基础篇

什么是Redis 与MySQL数据存在磁盘上不同的是,Redis数据以k-v的键值对形式存在内存中,支持持久化。由于存在内存中,其读写速度很快。 Redis为什么那么快 主要有三点: 基于内存,读写速度快IO多路复用、单线程读写有高效…

微信小程序教程011-1:京西购物商城实战

文章目录 1、起步1.1 uni-app简介1.2 开发工具1.2.1 下载HBuilderX1.2.2 安装HBuilderX1.2.3 安装scss/sass编译1.2.4 快捷键方案切换1.3 创建uni-app项目1.4 目录结构1.5 把项目运行到微信开发者工具1.6 使用Git管理项目1.6.1 本地管理1.6.2 把项目托管到码云1、起步 1.1 uni…

【深度学习】【语音】TTS, MATCHA-TTS,论文

https://arxiv.org/abs/2309.03199 文章目录 MATCHA-TTS: 一种基于条件流匹配的快速TTS架构摘要关键词1. 介绍2. 背景2.1. 近期编码器-解码器TTS架构2.2. 流匹配与TTS3. 方法3.1. 最优传输条件流匹配3.2. 提出的方法架构4. 实验4.1. 数据和系统4.2. 评估、结果和讨论5. 结论与未…