当前位置: 首页 > news >正文

【Linux】缓冲区和文件系统

在这里插入图片描述

个人主页~


缓冲区和文件系统

  • 一、FILE结构
    • 1、fd
    • 2、缓冲区
      • (一)有换行有return全部打印
      • (二)无换行无return的C接口打印
      • (三)无换行无return的系统调用接口打印
      • (四)有换行无return的C接口打印
      • (五)无换行有return的C接口打印
      • (六)深入理解缓冲区在用户空间
  • 二、文件系统
    • 1、固态硬盘
    • 2、逻辑地址LBA
      • (一)数据块 Data Blocks
      • (二)inode表 inode Table
        • (1)直接块指针
        • (2)一次间接块指针
        • (3)二次间接块指针
        • (4)三次间接块指针
      • (三)inode位图 inode Bitmap
      • (四)块位图 Block Bitmap
      • (五)块组描述符表 Group Descriptor Table
      • (六)超级块 Super Block

一、FILE结构

1、fd

FILE是在C中封装起来的一个结构体,那我们访问文件的时候都是通过fd访问的,自然在FILE中是封装了fd的,FILE结构体中,int _file存放的就是fd,其他的成员基本都是与缓冲区有关的
在这里插入图片描述

2、缓冲区

(一)有换行有return全部打印

看下面一段代码:
在这里插入图片描述

在这里插入图片描述

(二)无换行无return的C接口打印

很显然的,我们打印出了所有我们需要的内容,我们再看下一段

在这里插入图片描述

在这里插入图片描述
理想状态下我们应该是打印出结果后然后进行while一直循环,实际上是一只不会打印,这是为什么呢?是的,待在缓冲区里

首先我们要知道,缓冲区的大概位置,我们上面贴了一张FILE结构体的结构图,我们可以很清楚地看到缓冲区是FILE的成员指针指向的一块位置,也就是说缓冲区一定在用户空间而不是内核空间
在这里插入图片描述

(三)无换行无return的系统调用接口打印

我们在调用上面三个函数的时候,都是调用的C接口,自然都待在缓冲区里了,我们再看下一个程序
在这里插入图片描述

在这里插入图片描述
在这个程序中我们直接调用系统调用接口write,所以它不会经过C语言的缓冲区,而是直接打印

(四)有换行无return的C接口打印

我们再来看一组程序
在这里插入图片描述

在这里插入图片描述

这个程序和(二)程序的区别就只有换行,这告诉我们,C语言缓冲区对于显式器是行缓冲的,C语言标准库的文件流有三种缓冲模式,分别是全缓冲、行缓冲和无缓冲

全缓冲 _IOFBF :通常用于对磁盘文件的操作,数据会先被存储在缓冲区中,直到缓冲区被填满或者调用 fflush 函数、关闭文件(fclose)时,才会将缓冲区中的数据写入实际的文件,在全缓冲模式下,不会因为遇到换行符而自动刷新缓冲区
行缓冲 _IOLBF :常见于标准输入、标准输出等终端设备相关的流,当遇到换行符(\n)时,会自动刷新缓冲区,将缓冲区中的数据写入对应的设备或文件,某些情况下即使没有换行符,缓冲区满时也会刷新
无缓冲 _IONBF :标准错误输出通常默认是无缓冲的,确保错误信息能够立即显示,在无缓冲模式下,数据会立即写入对应的设备或文件,不会进行缓冲,因此不存在行刷新的概念

(五)无换行有return的C接口打印

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
进程退出return的时候,也会对缓冲区进行刷新

(六)深入理解缓冲区在用户空间

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们打印在显示器上的内容和打印在文件中的内容不一致,只有write打印了一遍,其他是按照顺序打印了两遍,我们当然能看出来这是fork的锅,接下来我们就深入理解谈一谈缓冲区

首先我们分析第一张结果图,因为显示器是行缓冲的,所以我们C接口的打印放到缓冲区中一行就会被打印到屏幕上一行,三条语句执行完之后缓冲区是空的,然后write再往上写,所以整个打印出来的顺序也是按照代码中来的

然后我们分析最后一张图,第一个我们可以肯定的是,打印到文件一定不是行缓冲,那就更不是无缓冲,实际上,由于文件是在存储硬件当中的,由于我们的效率问题,对于这种存储类的缓冲条件都是全缓冲,把缓冲区塞满再写入存储硬件中比塞一点写一点效率高得多,所以前三句C接口调用的打印全部在缓冲区中,然后write将自己打印,然后我们就碰到了fork,创建子进程,父子进程此时共享代码段和数据段,因为它们都没有做修改,然后我们就碰到了return 0,前面我们提到:进程结束也是要清空缓冲区的,此时父或子进程某一个先结束(由调度器决定),其中一个进程清空缓冲区的行为会引起另一个进程的写实拷贝,此时我们就有两份缓冲区,两个进程都结束都要清空缓冲区,自然在缓冲区中的内容要打印两份了(在这里要注意了,不只是子进程修改数据会引起子进程的写时拷贝,父进程对数据做修改时父进程也要发生写时拷贝,被写时拷贝的数据再再发生修改就直接修改了,不发生写实拷贝

二、文件系统

文件一般存储在硬盘当中,我们已经学习了动态的文件,也就是进程打开文件访问文件的过程,现在我们来学习一下静态的文件,我们来直接学习一下固态硬盘

1、固态硬盘

固态硬盘是一种基于NAND闪存的存储单元,我们常用的笔记本上的固态硬盘存储单元类型一般都是TLC的,三层单元,每个单元存储3bits,寿命较短成本较低,它通过电荷存储数据,通过高低电平区分0/1

NAND闪存的写入操作只能在已擦除的块上进行,擦除的最小单位就是块,通常为128KB-4MB,写入的最小单位是页,通常为4KB,所以它读的速度特别快,可以到微秒级,因为需要先擦除块,写的速度较慢,只能到毫秒级,每个块的擦写次数有限,超过后就会失效,一般TLC的擦鞋上限在500-1500次

这样的性质会带来一些不太好的结果,比如我们要写的内容很小,假设为4KB,那么我们先要擦除高达4MB的块才能进行写入,所以我们通过算法,将写入分散到所有块,避免某些块因为多次擦除而失效

固态硬盘控制器中的核心逻辑叫做FTL ( Flash Translation Layer ) Flash翻译层,负责将文件系统的逻辑地址映射到物理地址,是不是有点像进程地址通过页表映射到物理地址呢

接下来我们要学习文件系统的逻辑地址LBA,因为我们很清楚FTL映射到物理地址的过程是与页表映射是相似的,而逻辑地址的组织方式与进程地址可是不同的,虽然是有相似之处的~

2、逻辑地址LBA

LBA 从 0 开始,按照连续的整数顺序依次为存储设备中的每个数据块编号,存储设备中的每个数据块都对应一个唯一的 LBA 值,比如第一个数据块的 LBA 是 0,第二个是 1,依此类推,我们对应的数据块有Super Block、Group Descriptor Table、Block Bitmap、inode Bitmap、inode Table、Data blocks六个,最理想的情况下它们的LBA按照我上面写的顺序从0到5

我们把一块固态硬盘,我们笔记本上有一些品牌比如说某L开头的品牌,在我们购买的时候是默认给你带1T固态的,一般的品牌就是512G,我们拿到笔记本之后会对电脑进行分区,C盘作为系统盘分到最多的内存,G盘作为游戏盘给到300多G,然后D盘用来学习写代码,留个200G,EF盘用来存一些其他的东西,这样一套流程下来我们就分好盘了,我们说对硬盘做管理当然也是先描述后组织,Block Group就是组织和管理磁盘空间的一种重要结构
在这里插入图片描述
在n个Block Group之前有一个叫做Boot Block(引导块)的区域,在计算机启动过程中起着至关重要的作用,它是计算机启动过程的起点,没有引导块中的引导代码,计算机就无法知道如何加载操作系统,也就无法正常启动

我们按照知识理解易难顺序倒着往前来说

(一)数据块 Data Blocks

用来存储数据的块,NAND FLASH 内部的数据块由多个page组成,通常大小为4KB(现在也有8KB和16KB),这个page就是我们前面提到的最小写入单位:页
在这里插入图片描述

(二)inode表 inode Table

inode全称为索引节点,是一种数据结构,用于存储单个文件的全部属性,一般来说每个文件都有一个inode

struct inode
{//inode编号//文件类型//权限//引用计数//拥有者//所属组// 直接块指针unsigned long i_block[NUM];// 一次间接块指针unsigned long i_ind_block;// 二次间接块指针unsigned long i_dind_block;// 三次间接块指针unsigned long i_tind_block;
}

其中inode编号每个文件都是不同的,我们主要说说数据块指针

(1)直接块指针

直接块指针的NUM一般是12,它指向的位置是我们可以直接用来存储的位置,如果我们内容比较小(12*4KB = 48KB以内),那么直接块指针可以直接访问这些数据

(2)一次间接块指针

如果内容大于48KB,就需要一次间接块指针,一次间接块指针指向一个间接块,这个间接块存储中存储着多个指向数据块的指针,如我们的内容在(4KB/4b)*4KB = 4MB以内,通过一次间接块指针和直接块指针就可以访问这些数据

(3)二次间接块指针

二次间接块指针指向一个二次间接块,这个二次间接块存储中存储着多个指向间接块的指针,与一次间接块指针类似,这样我们存储的范围就达到了(4KB/4b)*(4KB/4b)*4KB = 4GB

(4)三次间接块指针

同上,最终我们最大的存储范围达到了 (4KB/4b)*(4KB/4b)*(4KB/4b)*4KB = 4TB
在这里插入图片描述

(三)inode位图 inode Bitmap

我们通过位图来和inode一一对应,位图上对应的比特位为0,那么该inode就没有被使用,可以被分配,如果为1则被占用,当从1变为0时,该inode又可以被分配了,其实这个过程就是一个删除的过程,一旦一个文件的inode无了,那么这文件是真的无了

在文件系统中,标识文件不是看它的名字,而是看它的inode,一旦inode和文件取消绑定了,那么操作系统就找不到这个文件了,再次写入其他内容的时候也就会被擦除覆盖了,换而言之,删除恒等于可以被覆盖

(四)块位图 Block Bitmap

我们通过位图来和数据块page一一对应,位图上对应的比特位为0,那么该页page就没有被使用,可以被分配,如果为1则被占用,当从1变为0时,该page又可以被分配了,如果我们要删除一块空间,只需要将它的对应的位置0,到再次被写入的时候就会消失了,当然我们的NAND闪存是定期擦除的,过一段时间它自己就被擦除了
在这里插入图片描述

(五)块组描述符表 Group Descriptor Table

记录了该块组的详细信息,包括块位图的位置、inode 位图的位置、inode 表的起始位置等,用于定位和管理块组内的各种数据结构

(六)超级块 Super Block

超级块是文件系统的核心,记录了文件系统的全局信息,如块大小、inode 数量、空闲块数量等,为了防止超级块损坏导致文件系统无法使用,每个块组中可能会包含超级块的副本,不过并非所有块组都有


今日分享就到这里啦~
在这里插入图片描述

相关文章:

【Linux】缓冲区和文件系统

个人主页~ 缓冲区和文件系统 一、FILE结构1、fd2、缓冲区(一)有换行有return全部打印(二)无换行无return的C接口打印(三)无换行无return的系统调用接口打印(四)有换行无return的C接口…...

函数式编程:概念、特性与应用

1. 函数式编程简介 函数式编程,从名称上看就与函数紧密相关。它是一种我们常常使用却可能并未意识到的编程范式,关注代码的结构组织,强调一个纯粹但在实际中有些理想化的不可变世界,涉及数学、方程和副作用等概念,甚至…...

git中的merge和rebase的区别

在 Git 中,git merge 和 git rebase 都是用于整合分支变更的核心命令,但它们的实现方式和结果有本质区别。以下是两者的详细对比: 一、核心区别 特性git mergegit rebase历史记录保留分支拓扑,生成新的合并提交线性化历史&#x…...

【目标检测】目标检测中的数据增强终极指南:从原理到实战,用Python解锁模型性能提升密码(附YOLOv5实战代码)

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

uniapp在app下使用mqtt协议!!!支持vue3

什么?打包空白?分享一下我的解决方法! 第一步 找大师算过了,装4.1版本运气好! 所以根目录执行命令… npm install mqtt4.1.0第二步 自己封装一个mqtt文件方便后期开坛做法! // utils/mqtt.js import mqt…...

VMware虚拟机17.5.2版本下载与安装(详细图文教程包含安装包)

文章目录 前言一、vmware虚拟机下载二、vmware虚拟机安装教程三、vmware虚拟机许可证 前言 VMware Workstation Pro 17 功能强大,广受青睐。本教程将带你一步步完成它的安装,简单易上手,助你快速搭建使用环境。 一、vmware虚拟机下载 VMwar…...

如何加固织梦CMS安全,防webshell、防篡改、防劫持,提升DedeCMS漏洞防护能力

织梦系统(DedeCMS)是一款非常知名的CMS系统,因其功能强大、结构科学合理,深受广大用户喜欢。 虽然织梦CMS(DedeCMS)非常优秀,但是为了保障网站安全,我们还是需要做一些必要的防护措…...

STM32的HAL库开发---ADC采集内部温度传感器

一、STM32内部温度传感器简介 二、温度计算方法 F1系列: 从数据手册中可以找到V25和Avg_Slope F4、F7、H7系列只是标准值不同,自行查阅手册 三、实验简要 1、功能描述 通过ADC1通道16采集芯片内部温度传感器的电压,将电压值换算成温度后&…...

Linux 命令大全完整版(12)

Linux 命令大全 5. 文件管理命令 ln(link) 功能说明&#xff1a;连接文件或目录。语  法&#xff1a;ln [-bdfinsv][-S <字尾备份字符串>][-V <备份方式>][--help][--version][源文件或目录][目标文件或目录] 或 ln [-bdfinsv][-S <字尾备份字符串>][-V…...

Python - 代码片段分享 - Excel 数据实时写入方法

文章目录 前言注意事项工具 pandas1. 简介2. 安装方式3. 简单介绍几个api 实战片段 - 实时写入Excel文件结束语 要么出众&#xff0c;要么出局 前言 我们在爬虫采集过程中&#xff0c;总是将数据解析抓取后统一写入Excel表格文件&#xff0c;如果在解析数据出现问题容易出现数据…...

(七)趣学设计模式 之 适配器模式!

目录 一、 啥是适配器模式&#xff1f;二、 为什么要用适配器模式&#xff1f;三、 适配器模式的实现方式1. 类适配器模式&#xff08;继承插座 &#x1f468;‍&#x1f469;‍&#x1f467;‍&#x1f466;&#xff09;2. 对象适配器模式&#xff08;插座转换器 &#x1f50c…...

DeepSeek 细节之 MoE

DeepSeek 细节之 MoE DeepSeek 团队通过引入 MoE&#xff08;Mixture of Experts&#xff0c;混合专家&#xff09; 机制&#xff0c;以“分而治之”的思想&#xff0c;在模型容量与推理成本之间找到了精妙的平衡点&#xff0c;其中的技术实现和细节值得剖思 Transformer 演变…...

【Linux-网络】从逻辑寻址到物理传输:解构IP协议与ARP协议的跨层协作

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;前言 &#x1f4d6; IP地址的组成 &#x1f516;IPv4 &#x1f516;IPv6 &#x1f4da…...

毕业离校管理系统的开发与需求分析

在当今信息化的时代背景下&#xff0c;高校的毕业生离校管理工作也逐渐向数字化转型。为了提高工作效率&#xff0c;减少人为错误&#xff0c;增强信息透明度&#xff0c;毕业离校管理系统应运而生。该系统旨在为学校提供一个高效、准确的毕业生离校管理平台&#xff0c;从而提…...

【NLP 24、实践 ⑤ 计算Bert模型中的参数数量】

以前不甘心&#xff0c;总想争个对错&#xff0c;现在不会了 人心各有所愿&#xff0c;没有道理可讲 —— 25.1.18 计算Bert模型结构中的参数数量 BertModel.from_pretrained()&#xff1a;用于从预训练模型目录或 Hugging Face 模型库加载 BERT 模型的权重及配置。 参数名称…...

一、Spring框架系统化学习路径

系统化的Spring框架学习路径 第1阶段&#xff1a;基础知识准备 Java基础 核心概念&#xff1a;面向对象、异常处理、集合框架、多线程等。JVM基础&#xff1a;内存模型、垃圾回收机制。 Maven或Gradle Maven&#xff1a;创建项目、依赖管理、生命周期。Gradle&#xff1a;基本…...

Midscene.js - AI驱动,轻松实现UI自动化

UI自动化测试一直是软件测试中的一项重要任务&#xff0c;而随着AI技术的快速发展&#xff0c;自动化测试的能力也在不断提升。如何让UI自动化更智能、精准、灵活&#xff1f;Midscene.js作为一款AI驱动的UI自动化测试工具&#xff0c;正逐步改变着传统自动化测试的面貌。你是不…...

(九)Mapbox GL JS 中 Marker 图层的使用详解

什么是 Marker&#xff1f; 在 Mapbox GL JS 中&#xff0c;Marker&#xff08;标记&#xff09; 是一个可视化元素&#xff0c;用于在地图上标记特定的地理位置。它可以是一个默认的图标、自定义的图像&#xff0c;或者任何 HTML 元素。Marker 不仅能显示位置&#xff0c;还能…...

2k1000LA 使能 nand.

背景 : 默认的 发货的镜像 确实 是识别不了 nand 的。 ------------------------------------------------------------------------------------------ 但是 我之前 已经写好了文档,因此 拷贝到线上。 1 首先我要使能这几个。 在menuconfig 中使能一下。...

Junit+Mock

base project <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.11</version><relativePath/></parent><dependencies><!--添加mysql依…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...