【linux】初步认识文件系统

初步认识文件系统

  • 前置知识的简单了解
  • 简单回顾C语言的文件操作
    • stdin&stdout&stderr
  • 系统文件IO
  • open函数的返回值
    • 文件描述符fd
      • 打开文件背后的操作
      • 文件描述符的分配规则

前置知识的简单了解

  1. 文件包括了文件内容和文件属性两个部分(文件内容顾名思义就是文件里面的数据等内容),而文件属性就是文件的相关信息
    在这里插入图片描述
    以上这些信息都是属于文件属性的范畴
  2. 要访问一个文件,必须先将文件打开,不管以什么形式打开文件(不论是编程语言的文件操作还是鼠标双击打开),都是将文件先加载到内存上的一个操作(也就是说在打开文件之前,访问文件的程序就已经运行起来了)
  3. 不论是以什么形式打开一个文件,文件是被进程打开的
  4. 一个进程可以打开多个文件
  5. 在一个时间段内,系统中会存在多个进程,那么也就意味这可能会存在更多的被打开的文件,作为操作系统,肯定是要管理这些被打开的文件。如何管理?(先描述,再组织),也就是说操作系统会去为每一个被打开的文件创建一个结构体,结构体中成员就是文件的各种信息即操作
  6. 不是所有的文件都被进程给打开了,没有被打开的文件被放到了磁盘当中
  7. 被打开的文件通常称为内存文件

简单回顾C语言的文件操作

  如果让你用C语言输出信息到显示器,你有哪些方法?

#include<stdio.h>
#include<string.h>
//分别用不同的方法向屏幕输出内容
int main()
{
      printf("printf\n");
      fprintf(stdout,"fprintf\n");
      fputs("fputs\n",stdout);
      const char*str="fwrite\n";
      fwrite(str,strlen(str),1,stdout);
      return 0;
}

以上程序输出结果为
在这里插入图片描述
  由此可见,虽然使用的不同的函数,但是通过不同的方法,同样可以往显示器上输出数据,就拿printffprintf来说,fprintf相较于printf只多了一个参数stdin,但是它们最后执行的结果都是一样的,那么这个stdin就值得我们去研究

stdin&stdout&stderr

  在C语言中,程序会默认打开三个流,分别是stdin(标准输入),stdout(标准输出)和stderr(标准错误),我们可以通过man手册来查阅这三个东西究竟是什么
在这里插入图片描述
  不难看出,这三个东西都是类型为FILE*的结构体指针,同时也是fopen的返回值类型,也就是文件指针,关于这个结构体里究竟有什么,接下来再慢慢分析

系统文件IO

  操作文件,除了C接口之外(当然其他的编程语言也有对应的文件操作),我们还可以使用系统调用接口来进行文件访问
  首先要认识到的一个系统调用接口就是open
在这里插入图片描述pathname:要打开或者创建的目标文件
flags:打开文件时,可以传入多个参数选项

参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
以上三个常量,必须指定一个且只能指定一个
O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写
O_TRUNC:若文件已存在,且打开文件是为了写,那么使用该选项就会将文件之前内容清空

  这些选项实质上类似于就是C语言中宏,所有的宏都是只有一个bit位上为1,其他bit位上为0,并且它们为1的bit位都是相互错位的
  这么说可能有些抽象,我在这里举个例子
在这里插入图片描述
在这里插入图片描述

  这里面的用#define定义的都是宏,当往Print中传参数的时候,通过按位或实现虽然只占用了已给参数的位置但是可以通过选项使执行的结构不同

返回值
成功:返回新打开的文件描述符
失败:返回-1(将错误码放到errno中)

mode:权限位(只有在需要创建文件时才会用到)
在这里插入图片描述
  这就是通过系统调用使用只读方式打开一个文件,并且使用系统调用close关闭文件,运行以上代码
在这里插入图片描述
  发现确实是在当前目录下创建了log,txt文件
  使用了以上系统调用,我们发现用以上open方式打开一个文件就和C语言的以只读方式打开文件非常的相似(系统调用的其他接口比如write、read、lseek等等都可以在C语言中找到类似的接口,这里就不再一一列举)

fopen=("log.txt","r");

  通过以上我们就可以大胆推测,C语言的文件操作有关的函数中是一定封装了系统调用接口。那么这个fd什么东西呢?不妨将这个fd打印以下看看
在这里插入图片描述
在这里插入图片描述  为了方便观察,可以一次性打开多个文件观察fd有什么特点
在这里插入图片描述
在这里插入图片描述
  我们发现打印的fd从3开始逐渐递增,这是要认识到fd到底有什么含义

open函数的返回值

  在认识返回值之前,先要明确两个概念:系统调用库函数。之前所提到的open和close就是系统提供的接口,我们称之为系统调用接口,而C语言的fwrite、fopen、fclose等等都是属于C标准库中的函数,我们称之为库函数
  当需要打开一个文件的时候,必定要先从磁盘中找到这个文件,然后将这个文件的文件内容和文件属性加载到内存当中。当我们向屏幕或者是其他地方打印字符串的时候,必定会需要访问硬件资源,比如我们使用到的printf函数向屏幕写入数据,显示器是硬件吗?答案是肯定的,所以你向显示器中写入数据本质上是向显示器这个硬件单元中写入数据;
  我们发现只要是发生了文件IO,不管是什么语言,最后一定是要和硬件产生关联。根据计算机系统的层状结构,最底层是各种硬件,然后是操作系统,接着是系统调用接口,最后才是用户层
  当一个C程序通过pritnf这样的库函数去访问硬件资源的时候,由于上面所述,C程序是不能直接去访问硬件资源的,它必须要通过操作系统来间接访问。因为操作系统是所有软硬件的管理者,它不允许应用层直接绕过操作系统去访问硬件,所以决定了在文件操作的时候,整个操作必须贯穿整个计算机体系的层状结构。
  站在操作系统的角度上,它必须提供一系列的系统调用为用户层服务(换句话说,操作系统要为我们提供一系列与文件相关的系统调用才有了C语言的一系列的文件操作)
  一句话总结:可以认为f#系列的函数,都是对系统调用的封装,方便二次开发

文件描述符fd

  通过之前的代码,我们可以知道,fd就是一个整数,但是不知道这个整数具体有什么含义

打开文件背后的操作

  当我们打开一个文件的时候,操作系统要在内存中创建相应的数据结构来描述,这个数据结构在linux中是一个结构体,叫做struct file,表示一个已经打开的文件对象(这个结构体对象中保存了文件相关的信息例如:inode、属性、方法集、权限等等,当然操作系统中会有多个文件被打开,自然内存中会有多个文件结构体,操作系统为了管理这些结构体,会将这些结构体用指针的方式连接起来,用链表的方式管理)
  在进程的task_struct当中存在一个类型为struct files*的结构体指针files,指向类型为struct files_struct的结构体,这个结构体中存在一个指针数组struct file* fd_array[],数组里面存的就是该进程所打开的文件所对应的文件对象,而文件描述符就是对应的数组下标
在这里插入图片描述

文件描述符的分配规则

  当我们直接打开一个文件
在这里插入图片描述
在这里插入图片描述

当我们关闭0或者2(这里以关闭0为例)
在这里插入图片描述
在这里插入图片描述
再次运行发现结果变为了0
文件描述符分配规则:在ffile_struct数组中,找到当前没有被使用的最小的下标,作为新的文件描述符

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VBA 读取sheet页中的指定区域数据,生成CSV文件

⏹待生成数据的sheet页 ⏹VBA代码 CreateObject("ADODB.Stream")&#xff1a;Microsoft ActiveX Data Objects (ADO) 库中的一个对象&#xff0c;用来处理文件的读写操作。Application.PathSeparator&#xff1a;系统默认的分隔符。Const startRowNum 4&#xff1a…

OpenCV(四)—— 车牌号识别

本节是车牌识别的最后一部分 —— 车牌字符识别&#xff0c;从一个完整的车牌图片到识别出车牌上的字符大致需要如下几步&#xff1a; 预处理&#xff1a;将车牌图片灰度化、二值化&#xff0c;并去除识别时的干扰因素&#xff0c;比如车牌铆钉字符分割&#xff1a;将整个车牌…

for循环赋值

在for循环内将i赋值给j的问题 for(int i0,ji1;i<5;i){//此时j只会等于1cout<<"i-"<<i<<" j-"<<j<<endl; }如图&#xff1a; 将j放入循环体后没问题 for(int i0;i<5;i){int j i1; cout<<"i-"<<…

关于一个error C2664错误代码的解析

具体错误信息如下所示&#xff1a; error C2664: “osgEarth::UID osgEarth::Util::ShaderFactory::addPreProcessorCallback(osg::Referenced *,std::function<void (std::string &,osg::Referenced *)>)”: 无法将参数 2 从“osgEarth::Util::PbrLightEffect::att…

40 生产者消费者模型

生产者消费者模型 概念 为何要使用生产者消费者模型&#xff0c;这个是用过一个容器解决生产者和消费的强耦合问题。生产者和消费者之间不需要通讯&#xff0c;通过阻塞队列通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xf…

41.WEB渗透测试-信息收集-域名、指纹收集(3)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;40.WEB渗透测试-信息收集-域名、指纹收集&#xff08;2&#xff09; 关于oneforall的安装…

DRF视图源码分析

DRF视图源码分析 1 APIView class GenericAPIView(APIView):pass # 10功能class GenericViewSet(xxxx.View-2个功能, GenericAPIView):pass # 5功能能class UserView(GenericViewSet):def get(self,request):passAPIView是drf中 “顶层” 的视图类&#xff0c;在他的内部主要…

SpringBoot+阿里云实现验证码登录注册及重置密码

开通阿里云短信服务 阿里云官网 创建API的Key 可以使用手机号或者刷脸来进行创建Key 创建成功 开通完成以后接下来实现代码请求阶段 配置maven依赖 <!-- 阿里云 oss 短信 依赖--><dependency><groupId>com.aliyun</groupId><artifactId>dysm…

Python的使用

1、打印&#xff1a;print&#xff08;‘hello’&#xff09; 2、Python的除法是数学意义上的除法 print&#xff08;2/3&#xff09; 输出&#xff1a;0.6666... 3、a18 a‘hello’ print(a) 可以直接输出 4、**2 表示2的平方 5、打印类型 print&#xff08;type&am…

【深度学习】第二门课 改善深层神经网络 Week 1 深度学习的实践层面

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;深度学习 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对…

R语言学习—6—多元相关与回归分析

1、引子 xc(171,175,159,155,152,158,154,164,168,166,159,164) #身高 yc(57,64,41,38,35,44,41,51,57,49,47,46) #体重 par(marc(5,4,2,1)) #设定图距离画布边缘的距离&#xff1a;下5&#xff0c;左4&#xff0c;上2&#xff0c;右1 plot(x,y) 2、相关…

【华为 ICT HCIA eNSP 习题汇总】——题目集20

1、&#xff08;多选&#xff09;若两个虚拟机能够互相ping通&#xff0c;则通讯过程中会使用&#xff08;&#xff09;。 A、虚拟网卡 B、物理网卡 C、物理交换机 D、分布式虚拟交换机 考点&#xff1a;数据通信 解析&#xff1a;&#xff08;AD&#xff09; 物理网卡是硬件设…

webpack 常用插件

clean-webpack-plugin 这个插件的主要作用是清除构建目录中的旧文件&#xff0c;以确保每次构建时都能得到一个干净的环境。 var { CleanWebpackPlugin } require("clean-webpack-plugin") const path require("path");module.exports {mode: "de…

docker 基础命令

docker 安装 更新系统 sudo apt update sudo apt -y dist-upgrade安装docker sudo apt-get -y install ca-certificates curl gnupg lsb-release sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/…

数据结构——链表(精简易懂版)

文章目录 链表概述链表的实现链表的节点&#xff08;单个积木&#xff09;链表的构建直接构建尾插法构建头插法构建 链表的插入 总结 链表概述 1&#xff0c;链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列元素。它由一系列节点&…

双链表的应用

cf edu161 D. Berserk Monsters 思路&#xff1a; 因为考虑到&#xff0c;每个怪是否死亡与其左右的怪息息相关&#xff0c;再者&#xff0c;若当前怪死亡&#xff0c;周围怪的相邻信息也会产生变化&#xff0c;由此可以想到使用双链表进行维护&#xff0c;双链表的维护方式有…

STM32——中断篇

技术笔记&#xff01; 1 中断相关概念 1.1 什么是中断&#xff1f; 中断是单片机正在执行程序时&#xff0c;由于内部或外部事件的触发&#xff0c;打断当前程序&#xff0c;转而去处理这一事件&#xff0c;当处理完成后再回到原来被打断的地方继续执行原程序的过程。 在AR…

算法学习系列(五十四):单源最短路的综合应用

目录 引言一、新年好二、通信线路三、道路与航线四、最优贸易 引言 关于这个单源最短路的综合应用&#xff0c;其实最短路问题最简单的就是模板了&#xff0c;这是一个基础&#xff0c;然后会与各种算法结合到一块&#xff0c;就是不再考察单个知识点了&#xff0c;而是各种知…

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1 1、 Dev.step(4)2、 Dev.step(-4) Dev.step(8)3、 Dev.turnLeft() Dev.step(4)4、 Dev.step(3) Dev.turnLeft() Dev.step(-1) Dev.step(4)5、 Dev.step(-1) Dev.step(3) Dev.step(-2) Dev.turnLeft() Dev.step(…

su03t语音模块烧录识别不出问题解决方法

今天被su03t模块的烧写问题&#xff0c;卡了一下午&#xff0c;也是非常困惑。所幸到现在已经能够解决问题&#xff0c;并且有一些心得&#xff0c;因此想要记录一下&#xff0c;也可以帮助有同样困惑的小伙伴。 首先我们来说一下接线问题&#xff0c;因为要利用到ch340&#x…