【LINUX】初识文件系统

文章目录

  • 一、前言
  • 二、回顾C语言文件操作
  • 三、初识系统调用
    • open
    • read
    • write
    • close
  • 四、文件系统初识
  • 五、结语

一、前言

二、回顾C语言文件操作

int main()
{
	FILE* fp = fopen("log.txt", "w");
	if (fp == NULL)
	{
		perror("fopen");
	}

	int cnt = 0;
	fputs("hello", fp);
	fclose(fp);
	return 0;
}

像我们使用的诸如:fopen、fclose、fputs等一系列函数,其实是C语言提供给我们的。这些函数分别封装了:open、close、write、read等一系列系统调用,向上提供给用户。

三、初识系统调用

open

标志位:
我们在函数中设置参数开关的话,虽然能达到达成某个条件就触发某个功能的效果,但如果传递多个标志位,就会显得拥堵,因此系统用一个整数flags、并用flags的每一个比特位表示一个标志位,这样一个int就可以同时至少传递32个比特位,绝对是够用的了。

open:

int open(const char* pathname,int flags);
int open(const char* pathname,int flags,mode_t mode);

系统调用open让我们能够按照一定方式打开一个文件,并给我们返回一个int类型的值。

pathname:代表文件的路径
flags:就是我们上面提到的标志位,标志位采用宏的方式设置,如O_RDONLY、O_WRONLY、O_TRUNC(清空文件原有内容)、O_APPEND(不清空文件原有内容)
mode:需要我们设置文件的权限(如果需要的话)

open的返回值:

如果使用open打开一个文件并接收这个函数的返回值,我们会发现这个返回值是数字3,那0、1、2去哪里呢?

其实open的返回值被称为 文件标识符 ,之所以从3开始,是因为任何进程在启动的时候都会默认打开三个流:标准输入流、标准输出流,标准错误流,这三个流占用了0、1、2的标识位。

read

ssize_t read(int fd, const void* buf,size_t len);

write

ssize_t write(int fd, const void* buf, size_t count);

close

close(int fd)

实际上,像C语言提供的fopen、fputs、fclose等函数,都是封装了这些系统调用,当我们使用fopen打开一个w文件时,其实在open中传入了多个标志位。不管任何语言如何封装,都是要调用底层的系统调用。

四、文件系统初识

文件如何管理

结合之前讲过的内容,我们知道进程在创建后会有一个task_struct的结构体,里面存放着进程相关内容,而这个结构体里存放着一个 结构体指针 files,这个指针指向的另一个结构体就存放着一个存放文件标识符的数组,并拿这个数组去寻找打开的各种文件。如图所示:

在这里插入图片描述
LINUX下的“一切皆文件”:

如图,我们使用操作系统的本质就是以进程的方式去访问当一个进程创建好以后,如果我们使用键盘和显示器读写操作的时候,进程会统一创建struct file结构体,其中包含文件的基本信息、缓冲区、以及函数指针来指向驱动程序提供操作硬件的方法,尽管各个设备的驱动方法不尽相同,但站在进程的视角,他只需要管理struct file这个结构体,这就是一切皆文件的理解。
在这里插入图片描述
重定向理解:

根据上面的理解,假如有这样一段代码:

int main()
{
	close(0)//关闭了标准输入流
	int fd = open("log.txt",O_RDONLY);
	int a,b;
	scanf("%d%d",&a,&b);
	
	return 0;
}

进程中,文件描述符分配:把下标最小的,没有使用的文件描述符分配给新文件。
由于我们已经把标准输入流(0)关闭,并打开了文件log.txt,此时log.txt的文件标识符就顺利成章的成了(0),因此我们就是从log.txt中读取数据了。

但这样关闭再重定向并不方便,我们也可以使用dup2函数来实现重定向:

int dup2(int oldfd ,int newfd) //将 oldfd 重定向到 newfd

如何做到重定向呢?

在上层无法感知的情况下,在OS内部,更改进程对应的文件描述符表中,特定下标的指向。

缓冲区理解:

先来思考一个问题:

int main()
{
  fprintf(stdout,"hello world\n");

  const char* msg = "hello write!\n";
  write(1,msg,strlen(msg));
  fork();             
  return 0;
}

运行两个命令为什么结果不同呢,为什么hello world被打印了两次呢??
在这里插入图片描述
要解释这个问题,我们需要结合重定向和刷新缓冲的策略来理解:

刷新策略:
a.显示器采用的刷新策略:行缓冲
b.普通文件采用的刷新策略:全缓冲

我们的程序里fprintf是C库提供的函数,我们在写入数据的时候,要先将数据写入C库提供的缓冲区内,按照刷新策略将内容拷贝到系统内相应的文件缓冲区,而write直接将数据拷贝到系统内相应的文件缓冲区,直接运行程序,由于显示器是行缓冲策略,因此fork的时候已经把数据都刷新到屏幕了。而重定向后,fprintf采用全缓冲的策略,但由于内容不会达到全缓冲要求,自然不会刷新,数据在C库的缓冲区一直到fork以后才能刷新 ,所谓的刷新即对其中内容清空,这样就会触发写时拷贝,父子进程自然都会刷新一次。
在这里插入图片描述

五、结语

到这里,今天的内容就全部结束了,如果感到对你有所帮助,欢迎三连支持,我们下次再见。

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

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

相关文章

spring2

1.Spring配置数据源1.1 数据源(连接池)的作用 数据源(连接池)是提高程序性能如出现的事先实例化数据源,初始化部分连接资源使用连接资源时从数据源中获取使用完毕后将连接资源归还给数据源常见的数据源(连接池):DBCP、C3P0、BoneC…

js实现一个简单的扫雷

目录先看下最终的效果:首先来分析一个扫雷游戏具有哪些功能分析完成后我们就开始一步步的实现1. 相关html和css2. 我们使用类来完成相应功能3. 之后我们则是要定义一个地图4. 对地图进行渲染5. 对开始按钮添加点击事件6. 现在我们可以实现鼠标左击扫雷的功能7. 给单…

网络知识汇总

文章目录一、 [网络拓扑结构](https://blog.csdn.net/weixin_52140964/article/details/127786157)二、[空间组网](https://blog.csdn.net/weixin_43509834/article/details/123225995)三、卫星网络发展历程四、SDN的由来五、ECMP、WCMP一、 网络拓扑结构 又称分布式结构。 任…

面试热点题:回溯算法 电话号码的字母组合与组合总和

前言: 如果你一点也不了解什么叫做回溯算法,那么推荐你看看这一篇回溯入门,让你快速了解回溯算法的基本原理及框架 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。…

2023/3/21总结

题解: E - 2xN Grid (atcoder.jp) 1.这一题,就是求出第一行与第二行相对应的相同数字的个数,看数据有多大,我们就知道,这道题目,是不可能穷举的。 2.因此,我们需要 找到规律去写它。此题需要…

最新消息!信息系统项目管理师教程改版!

《信息系统项目管理师教程(第4版)》于2023年3月出版 新版《信息系统项目管理师考试大纲》于2023年3月出版 信息系统项目管理师教程改版说明 一、整体说明 1、教材整体说明:第四版教材由25章组成,相比第三版28章内容减少了3章主要…

硬件速攻-AT24CXX存储器

AT24C02是什么? AT24CXX是存储芯片,驱动方式为IIC协议 实物图? 引脚介绍? A0 地址设置角 可连接高电平或低电平 A1 地址设置角 可连接高电平或低电平 A2 地址设置角 可连接高电平或低电平 1010是设备前四位固定地址 &#xf…

QT | 编写一个简单的上位机

QT | 编写一个简单的上位机 时间:2023-03-19 参考: 1.易懂 | 手把手教你编写你的第一个上位机 2.QT中修改窗口的标题和图标 3.图标下载 1.打开QT Creator 2.新建工程 Qt Creator 可以创建多种项目,在最左侧的列表框中单击“Application”&am…

学校教的Python,找工作没企业要,太崩溃了【大四真实求职经历】

如果只靠学校学的东西去找工作,能找到工作吗? 今天给大家看一个粉丝的真实求职案例,想做Python方面的工作,投了二十几个简历却没人要,心态崩了。为什么没人要?我来告诉你答案。 然后我还会结合我的这些年的…

Linux--线程安全、多线程fork问题

目录 一、概念: 二、利用空格分割字符串: 1.代码: 2.结果: 3.解决方法: 三、多线程fork() 1.代码: 2.线程id 3.增加fork()代码: 4.改变fo…

【嵌入式硬件芯片开发笔记】HART协议调制解调芯片AD5700配置流程

【嵌入式硬件芯片开发笔记】HART协议调制解调芯片AD5700配置流程 XTAL_EN接地,CLK_CFG的两个引脚由同一个GPIO控制 初始时HART_CLK_CFG输出低电平 由RTS引脚控制调制/解调。当RTS处于高电平时,为解调(输入);否则为调…

【计算机组成原理】:计算机系统概述

目录 一、计算机系统层次结构 1️⃣计算机系统的组成 2️⃣计算机硬件 1. 冯诺依曼机的基本思想 💤思考:冯诺依曼机的来源❓ 🌸知识点:冯诺依曼机的特点 💤思考:以运算器为中心的计算机有什么缺点❓ 2…

【微服务】—— 统一网关Gateway

文章目录1. 概述1.1 为什么需要网关1.2 SpringCloud Gateway2. gateway快速入门搭建网关服务1、创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:2、编写路由配置和nacos地址3. 断言工厂路由断言工厂Route Predicate Factory4. 过滤器…

【数据结构】千字深入浅出讲解队列(附原码 | 超详解)

🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:C语言实现数据结构 💬总结:希望你看完…

javaweb实习实训管理系统mysql

本毕业设计基于JSP的实习实训管理系统,本系统能实现网上的实习实训信息管理,主要功能有:添加用户、查看用户、管理用户、添加实验室、查看实验室、管理实验室、添加课程、查看课程、管理课程、添加教学、查看教学、管理教学、添加实习、查看实…

STM32的推挽输出和开漏输出

文章目录 前言一、推挽输出二、开漏输出三、区别和适应场景总结前言 本篇文章将带大家了解STM32的推挽输出和开漏输出,并且学习这两个的区别,学习分别在什么时候使用这两个不同的输出方式。 在 STM32 微控制器中,GPIO(General Purpose Input/Output)模块是一个通用的输入…

Java 到底是值传递还是引用传递?

C 语言是很多变成语言的母胎,包括 Java。对于 C 语言来说,所有的方法参数都是通过 “值” 传递的,也就是说,传递给被调用方法的参数值存放在临时变量中,而不是存放在原来的变量中。这就意味着,被调用的方法…

项目质量管理工作 不得不重视的4大关键点

1、三大视角确保项目质量 我们需要从客户视角、SOW视角和组织视角三大视角,确保项目的质量。 从客户视角方面出发,满足客户的要求,如项目交付的准时性、项目质量的保证等。我们需要全力保障客户对项目质量的要求。 从SOW视角确保项目质量&…

[ 漏洞复现篇 ] Joomla未授权访问Rest API漏洞(CVE-2023-23752)

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

Java实习生------MySQL10道面试题打卡

今日语录:“没有执行力,就没有竞争力 ”🌹 参考资料:图解MySQL、MySQL面试题 1、事务有哪些特性? 原子性: 一个事务中的所有操作,要么全部完成,要么全部不完成,不会出现…