打开文件 和 文件系统的文件产生关联

补充1:硬件级别磁盘和内存之间数据交互的基本单位
OS的内存管理
内存的本质是对数据临时存/取,把内存看成很大的缓冲区

物理内存和磁盘交互的单位是4KB,磁盘中未被打开的文件数据块也是4KB,所以磁盘中页帧也是4KB,内存中叫页框
在这里插入图片描述

我这个文件可能没有4KB,就一个字节,但不好意思加载4KB
我这个文件4KB,想修改1字节,也得加载4KB

为什么它不是要多少加载多少,而是一个固定大小4KB呢?
1、和磁盘交互比较慢,一共4KB每次要1KB的效率不如一气直接4KB,因为磁盘只需要定位一次
2、如果4KB文件你只要100字节,你能保证你下一次不用这文件上下文的其他数据吗?反正拿100字节还是4KB效率差不多,因为估摸着你后面的字节大概率也要用
局部性原理:正在访问代码区域附近也大概率会有数据代码被访问
这是一种预加载机制

那系统中向文件写了100字节,实际上保存100字节需要4KB?把数据交换的物理内存也要花4KB?
是的,文件大小从中做了一些事情
不用担心浪费问题,文件特别大前面那些内容把4KB都写满了,只有最后一个块被浪费了,小文件的就更不用说了

补充2:操作系统如何管理内存
在这里插入图片描述

操作系统必须能看到内存的物理地址
操作系统如何管理内存呢?
内存已经是一个一个4KB大小,非常多
我怎么知道哪些4KB被用到了,那些没被用
先描述,在组织!
struct page
{
//page页必要的属性信息
}
描述其中一个4KB
物理内存4G B 就有100多万的页
在这里插入图片描述
struct page mem_array[1048576];
对内存的管理变成了对数组的管理!!
数组天然是有下标的,所以每一个page天然有了页号的概念
如果此时任意一个地址0x11223344 & 0xFFFF F000,相当于求的是这个页的4KB对齐的起始地址
有了这个任意页的地址,应该就能通过找到对应的page数组对应的下标(我猜就是页地址也就是&完的地址减去第一个Page地址然后除以4就能得到下标)(都拿到地址了还有啥找不到的),进行物理内存管理
结论:
所有申请内存的动作,都是在访问内存page数组,都是对这个数组增删查改
在这里插入图片描述
在这里插入图片描述

struct page mem_array[1048576] 一定像链表一样有对应的数据结构方法,调算法申请内存

补充3:Linux中,我们的每一个进程、打开的每一个文件都要有自己的inode属性和自己的文件页缓冲区(内核缓冲区)

在开机时,把文件系统中的管理属性已经预加载到内存中了,尤其是super block GDT等文件系统方面的信息
比如这个分区上面就是操作系统文件,都要读,所以OS提前预加载到内存中
每个分区可能用的不同文件系统,OS中存在把所有的super block用双链表链接起来,OS知道每个分区大概在哪,每个分区文件系统什么样
在这里插入图片描述
关于打开一个文件时,OS要做什么工作,理解内核文件级缓冲区概念

打开一个文件时,struct file只保存了少数的文件属性,OS要为struct file构建一个数据结构struct inode才会保存文件的大部分属性,当打开文件时,根据对应目录中的数据块文件名映射找到inode编号,在已经预加载到物理内存中 的inode bitmap确认文件存在,然后在inode table 把对应的inode属性填入struct inode里

struct file 通过指针要能找到对应的struct inode,文件属性也就有了
在这里插入图片描述
内核中的struct file 与struct inode指针
在这里插入图片描述

文件属性其实不难找,文件内容呢?
C语言提供缓冲区,通过fprintf把数据写到缓冲区,通过fd我这个进程找到对应文件struct file
最终又怎么把数据写到对应磁盘上呢?
struct file中存在 address_space结构指针,这个结构包含一颗树page_tree,可以想象成一颗多叉树,树的节点中保存了指针数组,在叶子节点中保存了一个一个的struct page对象,而一个struct page对应物理内存4KB大小页框,所以应用层数据按照顺序从用户级缓冲区-> fd -> struct file -> address_space -> page_tree->叶子结点中的struct page然后再往物理内存中4KB中写入,就写到物理内存中了
我们看待物理内存时,只要找到对应的page,就能把数据写到物理内存里了
在这里插入图片描述
这颗树就叫文件的页缓冲区,此时我们把数据从应用层写到了由page管理的一个个内存中

补充4:
你说这玩意是个树,那是个什么树呢?
在这里插入图片描述
基数树 or 基树 本质是 字典树
数组有3个,那么这颗树就干上3层
void* slot[3]数组下标是数字,当我把他当成字母
每个数组又指向一个节点,就形成了这么一棵树
如果key是bca ,那么按照key的顺序就从根节点从上往下找
各种三个字母的组合就能根据这颗树找到某个底层叶子对象了
在这里插入图片描述

文件的内容是有偏移量的
假设文件大小10MB,也就是10x1024x1024字节
按照[0,1010241024]字节范围空间来看待
按照4KB来划分成一个一个的块
一共有多少个块呢?
1010241024/4*1024 = 2560个块
也就是说整个文件在磁盘上占2560个数据块
磁盘中每个块也就有了编号,从【1,2560】
每个数字乘以4096就是编号对应4KB在原始文件中的偏移量
所以把【1,2560】的编号按照Int来看待,有32bit位
假设0xFF FF FF FF 每八个bit看做一个字母Key = b,c ,a…
在这里插入图片描述

如果我们构建出这样的字典树,我们就可以拿着文件内容把文件内容的偏移量按照比特位分成特定的几个区域,八个bit为看成第一个字母b,后面依次类推,然后对应的字典树中就能找到整个文件中的偏移量和内存中page的映射关系
在这里插入图片描述
拿着文件的内容偏移量和内存的page建立映射关系,当我进行读写文件时,从开头读,结尾读,读写哪里,每一个读写都有偏移量,有偏移量找这颗树中偏移量对应的内存中某一个page,这样就能把数据保存到page里

其实最终想说的是文件写入把用户缓冲区的数据通过内核数据结构找到对应的Page对象把数据刷新到物理内存中了
接下来的工作就是OS要定期把数据刷到文件系统data blocks里面
在这里插入图片描述
此时数据已经写在物理内存中了,树里面的struct page就可以对应到物理内存中的page了
写完进程还管不管心数据刷到磁盘这个过程呢?
他就不关心了
所以这个数据刷新不刷新完全由OS决定,从这开始就往驱动层面走了
在这里插入图片描述

总结:
1、一个磁盘对应的文件它在访问之前部分对应文件系统中的属性已经加载内存了
2、进程打开文件时,本质就是把磁盘中的属性往struct inode 放
内容blocks通过struct file也能找到,以page的形式保存好
3、用户层写入时,通过fd-》 struct file-》 address-》 找到管理基树 找到物理内存中对应的page
然后把数据刷新到对应page页里,最后由OS调用IO子系统,把数据通过IO队列刷新到硬件上

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

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

相关文章

【AI视野·今日CV 计算机视觉论文速览 第277期】Fri, 27 Oct 2023

AI视野今日CS.CV 计算机视觉论文速览 Fri, 27 Oct 2023 Totally 93 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers A Coarse-to-Fine Pseudo-Labeling (C2FPL) Framework for Unsupervised Video Anomaly Detection Authors Anas Al lahham…

Xrdp+Cpolar实现远程访问Linux Kali桌面

XrdpCpolar实现远程访问Linux Kali桌面 文章目录 XrdpCpolar实现远程访问Linux Kali桌面前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于…

【Spring Cloud】黑马头条 用户服务创建、登录功能实现

点击去看上一篇 一、创建用户 model 1.创建用户数据库库 leadnews_user 核心表 ap_user 建库建表语句 这里一定要使用 navicat,执行SQL 文件,以防止 cmd 中的编码问题 先将 SQL 语句,保存在电脑中,再使用 navicat 打开 CREATE…

代码静态测试工具之cppcheck

cppcheck简介 Cppcheck is an analysis tool for C/C code. It provides unique code analysis to detect bugs and focuses on detecting undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate as few f…

数据库期末考前复习题(单选+多选+判断+解答)

文章目录 #数据库考前复习题一、 选择1.单选题2.多选题 二、判断题三、解答请描述数据库中的三大范式关系型数据库ACID特性 #数据库考前复习题 一、 选择 1.单选题 1.使用limit进行分页查询,其中每页10条数据,查询第5页应该写为? SELECT *…

java: 程序包XXX.XXX.XXX不存在解决方法

背景介绍: com.DXG.bean 来源于同一个项目底下的另一个包 问题所在: 明明已经引入了相关包 但是编译的时候报错:java: 程序包com.DXG.bean不存在 问题分析: 怀疑是拆模块以后引入相关包没有将相关包下载到本地maven仓库中 所以…

Qt QLable 字符过长省略

前言: 项目中常用到字符过长问题,Qt默认的省略并不好用,不是自己想要的; QFontMetri 可使用 QFontMetri 当text的像素宽度超过width,将返回字符串的一个省略版本取决于mode。否则将返回原字符串; mode…

C++面向对象编程(3)——常用关键字介绍(TODO)

本篇会逐步添加一些C的关键字,持续更新... 一. default 1.1 场景 如果对构造函数进行了重载,则编译器不会隐式的生成一个默认的构造函数,此时如果调用了默认构造函数会在编译时报错,但是很多时候我们是需要默认构造函数的。如何…

基于IDEA创建Maven工程及注意事项

Java全能学习面试指南:https://javaxiaobear.cn 1. 概念梳理Maven工程的GAVP Maven工程相对之前的项目,多出一组gavp属性,gav需要我们在创建项目的时候指定,p有默认值,我们先行了解下这组属性的含义: Ma…

Mac电脑VSCode配置PHP开发环境

1.安装 PHP 首先,打开终端,安装 Homebrew,输入如下命令: $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装了 Homebrew 之后,你可以使用下面的…

Apache Airflow (八) :DAG任务依赖设置

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹…

User parameters自定义用户参数 (zabbix监控)

1、介绍和用法 ① 介绍 自定义用户参数,也就是自定义key 有时,你可能想要运行一个代理检查,而不是Zabbix的预定义 你可以编写一个命令来检索需要的数据,并将其包含在代理配置文件("UserParameter"配置参数)的用户参数中…

LabVIEW关于USRPRIO的示例代码

LabVIEW关于USRPRIO的示例代码 USRPRIO 通常以两种方式使用: 1 基于 FPGA 的编程 对于希望修改USRP上的底层FPGA代码以添加自定义DSP模块的应用,请使用USRP示例项目。它可作为构建 USRP RIO 流式处理应用程序的起点,可从“创建项目”对话框…

服务注册发现 springcloud netflix eureka

文章目录 前言角色(三个) 工程说明基础运行环境工程目录说明启动顺序(建议):运行效果注册与发现中心服务消费者: 代码说明服务注册中心(Register Service)服务提供者(Pro…

基于JavaWeb+SSM+社区居家养老服务平台—颐养者端微信小程序系统的设计和实现

基于JavaWebSSM社区居家养老服务平台—颐养者端微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 在复杂社会化网络中,灵活运用社会生活产生的大数据&am…

Shopee买家号有什么作用?如何才能拥有大量的虾皮买家号?

对于卖家而言,用shopee买家号进行测评有以下几点好处: 1、随时随地可以给自己店铺下单、评价、点星 2、成本很低:都是自己准备一些资料进行注册的,因此成本也是比较可控的。 3、自己管理更加安全可控:每个账号都是独…

03-关系和非关系型数据库对比

关系和非关系型数据库对比 关系型数据库(RDBMS):MySQL、Oracl、DB2、SQLServer 非关系型数据库(NoSql):Redis、Mongo DB、MemCached 插入数据结构的区别 传统关系型数据库是结构化数据,向表中插入数据时都需要严格的约束信息(如字段名,字段数据类型,字…

C#WPF中的实现读取和写入文件的几种方式

说明:C#中实现读取和写入的类根据需要来选择。 1、File类 File类是用于操作文件的工具类,提供了对文件进行创建、复制、删除、移动和打开单一文件的静态方法。但需要注意的是,WPF中使用File的类,需要先引用System.IO下的命名空间。…

从零开始:打造疫苗预约抖音小程序的技术指南

这篇文章小编将与大家一同探讨如何开发一款疫苗预约的抖音小程序。 第一步:项目准备和规划 确定用户需要提供的信息,例如个人信息、接种地点偏好等。同时,考虑系统的用户界面设计,确保用户友好性和易用性。 第二步:…

验证k8s中HPA功能及测试

部署 使用yaml部署服务 apiVersion: apps/v1 kind: Deployment metadata:name: php-apachenamespace: tools spec:replicas: 1selector:matchLabels:app: php-apachetemplate:metadata:labels:app: php-apachespec:containers:- name: php-apacheimage: registry.cn-beijing.…