深入理解linux中的文件(下)

目录

一、语言级缓冲区和内核级缓冲区

 二、C语音中的FILE* fp = fopen(“./file.txt”,"w"):

四、理解磁盘结构:

物理结构

逻辑结构

五、未被打开的文件:

六、更加深入理解inode编号怎么找到文件:        

七、对路径结构进行缓存:   

1. 路径名解析加速

2. 更新多叉树的路径

3. 进程如何使用 dentry

(1)打开文件

(2)路径遍历


一、语言级缓冲区和内核级缓冲区

        编程语言运行在操作系统之上,并利用操作系统的功能来完成各种任务。当我们提到语言级缓冲区时,它实际上是在操作系统“看不见”的应用层面上工作的。

        如果没有语言级缓冲区,在C语言中每次使用fwritefprintf函数写数据时,都会直接调用系统底层的write函数,这会导致频繁的数据传输,耗费更多时间。为了避免这种情况,我们在程序里设置了语言级缓冲区。这样,当你使用fwritefprintf时,数据首先存入这个语言级缓冲区。只有当满足一定条件时,才会一次性把大量数据传给操作系统处理。至于什么时候这些数据最终被保存到硬盘上,则由操作系统决定。

语言级缓冲区刷新的方式有三种:

  1. 对于显示输出(比如打印到屏幕上),每当遇到换行符\n就会自动刷新缓冲区。
  2. 对于普通文件(保存在磁盘上的文件),当缓冲区满了的时候会自动刷新。
  3. 使用fflush()函数可以手动强制刷新缓冲区,立即把数据写出去。

 二、C语音中的FILE* fp = fopen(“./file.txt”,"w"):

1. 在当前目录下创建一个file.txt文件,模式是写入。

2. 返回一个FILE结构体指针

二、C语音中的fclose的作用:

  1. 刷新缓冲区:如果文件是以写模式(如 "w""a")打开的,调用 fclose() 会首先将缓冲区中的所有未写入数据强制写入到文件中。这确保了所有通过程序写入的数据都被正确地保存到了文件里。

  2. 释放资源:关闭文件后,fclose() 会释放分配给该文件流的所有系统资源。这包括内存中的缓冲区和其他与文件操作相关的资源。这对于保持程序的效率和避免资源泄漏非常重要,尤其是在程序需要处理多个文件或长期运行的情况下。例如:销毁FILE结构体

四、理解磁盘结构:

 

物理结构

  1. 盘片(Platters):硬盘内部由一个或多个圆形盘片组成,这些盘片是实际存储数据的地方。每个盘片都有两面,称为记录面。

  2. 磁道(Tracks):盘片上的表面被划分为若干个同心圆,每一个这样的圆被称为磁道。所有盘片上相同位置的磁道合在一起形成柱面(Cylinder)。

  3. 扇区(Sectors):每个磁道进一步被分割成多个弧段,每个弧段即为一个扇区。标准的扇区大小通常是512字节或4KB(高级格式化技术)。扇区是磁盘读写的最小单位。

  4. 柱面(Cylinders):所有盘片上相同编号的磁道共同构成一个柱面。柱面的概念主要用于描述磁盘的三维地址空间。

  5. 磁头(Heads):用于读取和写入数据的装置。每个盘片的每一面都有一个对应的磁头。(注意:各个读写磁头不会分开移动,而是由一个移动臂控制所以的磁头,一起前进后退)

由于磁盘的三维的物理结构,把每一个扇区当成一个数组的格子,就可以把他抽象成一个三维数组。而三维数组又可以抽象成一个超大的一维数组。 

逻辑结构

  1. 分区(Partition):物理磁盘可以被划分成一个或多个逻辑部分,每个部分称为分区。例如,在Windows系统中的C盘和D盘就是不同的分区。每个分区都可以有自己的文件系统,并像独立的磁盘一样使用。

  2. 分组(Block Group):在Ext4等Linux文件系统中,每个分区可以进一步划分为多个块组。这种划分有助于提高性能并简化管理。

  3. 超级块(Superblock):在linux文件系统中,超级块包含了关于文件系统的元数据,比如块大小、空闲块数量、inode信息等。(重点:Superblock是管理区的,所以不是每一个组中都含有Superblock。如果Superblock损坏了,就找不到几百个G的区了,,所以Superblock也不能只有一个,整个区中会有两三个Superblock作为备份)

  4. 组描述符表(Group Descriptor Table):包含组中的信息:

    1. 数据块位图(Block Bitmap)的位置和状态,用于跟踪哪些数据块已被使用,哪些仍然空闲。

    2. inode位图(Inode Bitmap)的位置和状态,用于跟踪哪些inode已被分配,哪些未被使用。

    3. inode表(Inode Table)的位置,其中包含了该块组内所有文件和目录的inode信息。
    4. 数据块(Data blocks)的数量以及其他相关信息。
  5. 数据块位图 和 inode位图:使用二进制0和1表示空闲和占用的情况。

  6. inode表:inode表中包含很多的inode结构体,通常一个inode结构体大小为128字节。

  7. 索引节点(Inode):在Unix/Linux文件系统中,每个文件都有一个对应的inode,它存储了文件的元数据(如权限、所有权、大小等)以及指向文件数据块的指针。(重点:文件名不存储到inode结构体中

  8. 数据块:每一个数据块是4KB大小,里面存放文件的内容,当然,数据块,也会存放指针。这些指针指向其他的数据块,也就是一个数据块有1KB的指针。

    1. 一级间接块索引表指针,1KB*4KB=4MB大小,就可以存储4MB大小的文件。

    2. 二级索引:4KB * 1KB * 1KB = 4GB。

    3. 三级索引:4KB * 1KB * 1KB = 4TB。

    4. 到了三级索引就够了,一个文件不会有那么大的,太大了我们也会把他拆小。一个文件太大,你内存放不下,也打不开。

五、未被打开的文件:

        未被打开的文件都存储在磁盘上。如果你想访问这些文件,你需要知道它们的具体路径。明明在linux,操作系统只认识inode编号,那么文件路径怎么帮助操作系统找到文件的确切位置?

         在Linux系统中,每个目录不仅包含文件名,还存储了指向这些文件的inode信息。这意味着目录实际上保存了一个文件名与inode编号之间的映射表

       例如,如果你有一个文件路径为 /home/chen/communication/mypipe.cc,以下是系统如何找到这个文件的过程:

  1. 从根目录 / 开始,系统会根据路径进入 home 目录。
  2. 在 home 目录下,系统查找名为 chen 的子目录及其对应的inode编号(比如 chen:13425)。这里的 13425 是一个示例inode编号,实际编号可能不同。
  3. 使用这个inode编号,系统可以定位到 chen 目录。然后在 chen 目录中继续查找 communication 子目录及其inode信息。
  4. 最终,在 communication 目录中找到 mypipe.cc 文件的inode编号,这样就可以读取该文件的内容了。

        需要注意的是,根目录 / 的inode是固定的,这保证了系统始终可以从根目录开始导航至任何文件或目录。这种机制使得即使文件系统非常庞大,也可以高效地定位和管理文件。

通过这种方式,Linux文件系统能够有效地管理和检索文件,同时保持数据的一致性和完整性。

六、更加深入理解inode编号怎么找到文件:        

        当我们获得了某个文件的inode编号(例如13425),接下来需要定位并读取该inode的具体信息来访问文件的内容和属性。

  1. 查找组描述符表:首先,系统会根据inode编号确定该inode属于哪个块组。然后从这个块组的组描述符表中获取相关信息。组描述符表包含了关于该块组的重要信息,比如起始inode编号(例如13400)和结束inode编号(例如13700)。

  2. 计算相对位置:知道了块组的起始inode编号(如13400),我们可以用目标inode编号减去起始inode编号(即13425 - 13400 = 25)。这样我们就得到了目标inode在该块组内的相对位置——这里是第25个inode。

  3. 访问inode表:接着,系统会在该块组的inode表中查找第25号区域中的inode结构体。每个inode结构体通常包含文件的元数据(如权限、所有权、大小等)以及指向文件数据块的指针。

  4. 读取文件内容和属性:一旦找到了正确的inode结构体,我们就可以使用其中的信息来定位文件的数据块,进而读取文件的实际内容及其属性。

通过这种方式,即使文件系统非常庞大,操作系统也能高效地定位和访问任何文件。

七、对路径结构进行缓存:   

        当我们访问文件时,并不是每次都从根目录开始逐层查找,因为这样的效率非常低——实际上,大约99%的文件很少被打开。为了解决这个问题,我们使用多叉树的方式来缓存路径结构。相比直接使用目录结构体,这种多叉树结构更简单,查找速度也更快。

1. 路径名解析加速

        当一个进程尝试访问某个文件时,它提供的是文件的路径名。内核需要将这个路径名转换为具体的 inode。通过使用 dentry 结构体,内核可以快速找到对应路径的 inode,而不需要每次都从磁盘读取信息。多叉树的每个节点都是一个 dentry 结构体,定义如下:

struct dentry {
    char *name;               // 节点名称
    struct inode *inode;      // 指向inode的指针
    struct dentry *parent;    // 父节点指针
    struct list_head children; // 子节点链表头
};

2. 更新多叉树的路径

        当访问一个新的路径时,如果该路径不存在于当前缓存中,则需要创建新的 dentry 节点,并将其添加到正确的父节点的子节点列表中。同时更新父节点的相关信息,例如增加子节点计数等。

3. 进程如何使用 dentry

(1)打开文件

        当一个进程调用 open() 系统调用打开一个文件时,内核会首先通过文件结构体中的 dentry指针,进行查找dentry 缓存中查找该文件的路径。如果找到了,就可以直接获取对应的 inode 和文件描述符;如果没有找到,则需要从磁盘读取相关信息并更新缓存。

(2)路径遍历

        对于任何涉及路径的操作(如 stat(), unlink() 等),内核都会通过 dentry 结构进行路径名解析。这通常涉及到从根目录开始逐步向下遍历直到找到目标文件或目录。

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

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

相关文章

零基础Vue入门6——Vue router

本节重点: 路由定义路由跳转 前面几节学习的都是单页面的功能(都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html),涉及到项目研发都是有很多页面的,这里就需要用到路由(vue route…

京准:NTP卫星时钟服务器对于DeepSeek安全的重要性

京准:NTP卫星时钟服务器对于DeepSeek安全的重要性 京准:NTP卫星时钟服务器对于DeepSeek安全的重要性 在网络安全领域,分布式拒绝服务(DDoS)攻击一直是企业和网络服务商面临的重大威胁之一。随着攻击技术的不断演化…

网络计算机的五个组成部分

单个计算机是无法进行通信的。所以需要借助网络。 下面介绍一些在网络里常见的设备。 一、服务器 服务器是在网络环境中提供计算能力并运行软件应用程序的特定IT设备 它在网络中为其他客户机(如个人计算机、智能手机、ATM机等终端设备)提供计算或者应用…

MATLAB实现单层竞争神经网络数据分类

一.单层竞争神经网络介绍 单层竞争神经网络(Single-Layer Competitive Neural Network)是一种基于竞争学习的神经网络模型,主要用于数据分类和模式识别。其核心思想是通过神经元之间的竞争机制,使得网络能够自动学习输入数据的特…

【漫画机器学习】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归(Ridge Regression)中的 α 值 岭回归(Ridge Regression)是一种 带有 L2​ 正则化 的线性回归方法,用于处理多重共线性(Multicollinearity)问题,提高模型的泛化能力。其中&am…

网络安全 | 零信任架构:重构安全防线的未来趋势

网络安全 | 零信任架构:重构安全防线的未来趋势 一、前言二、零信任架构的核心概念与原理2.1 核心概念2.2 原理 三、零信任架构的关键技术组件3.1 身份管理与认证系统3.2 授权与访问控制系统3.3 网络与安全监测系统3.4 加密与数据保护技术 四、零信任架构与传统安全…

网络爬虫学习:借助DeepSeek完善爬虫软件,增加停止任务功能

一、引言 我从24年11月份开始学习网络爬虫应用开发,经过2个来月的努力,终于完成了开发一款网络爬虫软件的学习目标。这几天对本次学习及应用开发进行一下回顾总结。前面已经发布了两篇日志: 网络爬虫学习:应用selenium从搜*狐搜…

JVM图文入门

往期推荐 【已解决】redisCache注解失效,没写cacheConfig_com.howbuy.cachemanagement.client.redisclient#incr-CSDN博客 【已解决】OSS配置问题_keyuewenhua.oss-cn-beijing.aliyuncs-CSDN博客 【排坑】云服务器docker部署前后端分离项目域名解析OSS-CSDN博客 微服…

VScode如何使用deepseek详细教程

本章教程,主要介绍如何在vscode中,安装使用deepseek教程。deepseek生成式人工智能模型最近可是非常的热门。感兴趣的可以尝试看看吧。 一、注册deepseek账号 注册登录地址:https://platform.deepseek.com/api_keys 注册登录账号之后,创建一个API key ,将这个API key复制下…

大数据相关职位介绍之三(数据挖掘,数据安全 ,数据合规师,首席数据官,数据科学家 )

大数据相关职位介绍之三(数据挖掘,数据安全 ,数据合规师,首席数据官,数据科学家 ) 文章目录 大数据相关职位介绍之三(数据挖掘,数据安全 ,数据合规师,首席数据…

[基础]端口隔离实验

实验教程 隔离类型 双向隔离:统一端口隔离组的接口之间隔离,不同端口隔离组的接口之间不隔离,端口隔离只针对同一设备上的端口隔离组成员,对于不同设备上的接口而言无法实现。单向隔离:实现不同端口隔离组的接口之间的…

vscode 如何通过Continue引入AI 助手deepseek

第一步: 在deepseek 官网上注册账号,得到APIKeys(deepseek官网地址) 创建属于自己的APIKey,然后复制这个key,(注意保存自己的key)! 第二步: 打开vscode,在插件市场安装Continue插件, 点击设置,添加deepseek模型,默认…

FPGA的IP核接口引脚含义-快解

疑问 手册繁琐,怎样快速了解IP核各输入输出接口引脚的含义。 答疑 不慌不慌,手册确实比较详细但繁琐,如何快速知晓该部分信息,涛tao道长给你们说,简单得很,一般新入门的道友有所不知,往往后面…

“AI隐患识别系统,安全多了道“智能护盾”

家人们,在生活和工作里,咱们都知道安全那可是头等大事。不管是走在马路上,还是在工厂车间忙碌,又或是住在高楼大厦里,身边都可能藏着一些安全隐患。以前,发现这些隐患大多靠咱们的眼睛和经验,可…

RocketMQ中的NameServer主要数据结构

1.前言 NameServer是RocketMQ中的一个比较重要的组件,我们这篇博客针对NameSever中包含的组件进行分析,分析一下NameServer中包含的组件以及组件的作用。以前我有一篇博客中rocketMq源码分析之搭建本地环境-CSDN博客,在这篇博客中就简单看了…

8-登录流程

在AppStartInitFinish_CreateLoginUI.初始化后,执行Login界面的初始化 登录面板逻辑:UILoginComponentSystem,针对组件UILoginComponent创建的System 登录面板逻辑:UILoginComponent 逻辑层: LoginHelper中的clientSenderComponent.LoginA…

基于HAI部署DeepSeekR1的招标文书智能辅助生产开发与应用

一、前言 1.1行业背景 在日常商业活动中,招投标流程往往是企业竞标和项目落地的关键一环。其中,招标文书的编写工作对于投标企业极具挑战:既要保证逻辑清晰、条理分明,又必须遵循招标机构的各类格式规范,甚至还有特定…

SQL/Panda映射关系

Pandas教程(非常详细)_pandas 教程-CSDN博客 SQL:使用SELECT col_1, col_2 FROM tab; Pandas:使用df[[col_1, col_2]]。 SQL:使用SELECT * FROM tab WHERE col_1 11 AND col_2 > 5; Pandas:使用df…

Sentinel的安装和做限流的使用

一、安装 Release v1.8.3 alibaba/Sentinel GitHubA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) - Release v1.8.3 alibaba/Sentinelhttps://github.com/alibaba/Senti…

院校联合以项目驱动联合培养医工计算机AI人才路径探析

一、引言 1.1 研究背景与意义 在科技飞速发展的当下,医疗人工智能作为一个极具潜力的新兴领域,正深刻地改变着传统医疗模式。从疾病的早期诊断、个性化治疗方案的制定,到药物研发的加速,人工智能技术的应用极大地提升了医疗服务…