Linux中文件的读写过程

文件的读取过程

在Linux系统中,读取文件的过程主要由操作系统内核通过文件系统与存储设备的交互来完成。以下是文件读取过程的详细步骤:

1. 系统调用阶段

当用户程序(如catless)请求读取文件时,会调用系统调用(如open()read())来请求访问文件。这些调用会传递文件路径等参数给内核。

2. 路径解析

内核接收到文件路径后,通过文件系统来解析路径。路径解析是一个递归的过程,文件路径可能包含多个目录,所以内核需要从根目录开始一个个解析,最终找到文件所在的具体目录。

3. 检查文件缓存(Page Cache)

在读取文件之前,内核会首先检查文件是否已经被加载到内存中的页面缓存(Page Cache)。如果文件已经在缓存中,内核可以直接从内存读取数据,而无需访问磁盘,这样可以加快文件读取速度。

4. VFS(虚拟文件系统)层

如果文件没有在缓存中,Linux会通过虚拟文件系统(VFS)来处理文件操作。VFS是一个抽象层,支持多种不同的文件系统(如ext4、xfs、btrfs等)。VFS负责统一处理与具体文件系统的交互,包括文件元数据的管理,如权限检查、文件类型等。

5. 文件系统级别操作

VFS解析完文件路径后,会将操作传递给具体的底层文件系统(如ext4)。此时,文件系统会通过访问磁盘来读取文件的元数据(如inode和数据块的映射关系)。

6. 读取inode

文件系统会从磁盘中读取文件的inode(索引节点)。inode包含文件的元数据,如文件大小、创建时间、权限信息,以及数据块的地址。通过inode,文件系统可以知道文件数据存储在哪些数据块中。

7. 数据块读取

文件系统根据inode中的信息,读取相应的数据块。这些数据块可能散布在磁盘的不同区域。现代文件系统通常会使用磁盘调度算法来优化读写性能,尽量减少磁盘寻道时间。

8. 缓存到Page Cache

当文件数据从磁盘读取后,会被加载到Page Cache中,方便后续读取时加快速度。如果数据已经存在于Page Cache,则可以跳过这个步骤。

9. 返回给用户空间

文件的数据被读取到内核空间后,通过系统调用(如read())将数据返回给用户空间程序。程序可以选择继续读取文件的其他部分,或者关闭文件结束操作。

10. 文件关闭

当文件不再需要时,用户程序会调用close()系统调用来关闭文件。内核释放文件的相关资源,如文件描述符和缓存。

总结:

  • 用户发起系统调用(如openread
  • 内核通过VFS解析路径并检查缓存
  • 读取或缓存文件的inode和数据块
  • 文件系统将数据从磁盘传递回用户程序

这个过程的优化,如Page Cache的使用,极大提升了文件读取的效率。

文件的写入过程

在Linux系统中,文件的写入过程与读取过程类似,但有一些额外的步骤涉及数据一致性和缓存管理。文件写入过程包括以下主要阶段:

1. 系统调用阶段

用户程序(如echocpvim)发起写入操作时,会调用系统调用(如open()write())来请求写入文件。系统调用会把写入的数据以及文件描述符传递给内核。

2. 路径解析

在写入文件前,内核需要通过路径解析确定文件的实际位置。这与读取操作中的路径解析过程相同,内核递归地从根目录开始解析文件路径,直到找到目标文件或目录。

3. 检查文件是否可写

在找到文件后,内核会检查文件的权限(如通过inode中的权限位)以确保当前用户具有写入文件的权限。如果没有写入权限,系统调用会返回错误。

4. 文件缓存(Page Cache)

与读取文件类似,内核在写入文件时也会先检查文件是否已经存在于Page Cache中。如果文件在缓存中,写入操作首先会修改缓存中的数据。

如果缓存中没有该文件的数据,内核会从磁盘读取文件相应部分到Page Cache中,然后在Page Cache中进行数据的修改,而不是直接写入磁盘。

5. 数据写入到Page Cache

用户写入的数据会首先被写入Page Cache,而不会立即写入磁盘。这是为了优化性能,避免频繁的磁盘I/O操作。此时,文件的内容被缓存,但数据尚未同步到实际存储介质中。

6. 标记脏页(Dirty Pages)

当数据被写入到Page Cache后,内核会标记缓存中的相关页面为“脏页”(Dirty Pages),即这些页面包含未写入到磁盘的更改。脏页会在适当的时机被写回到磁盘,确保数据最终存储到持久性介质中。

7. 同步写入操作(可选)

如果用户程序使用了fsync()fdatasync()等系统调用,则会强制内核立即将文件的脏数据写回磁盘,确保数据持久化。这种同步操作保证了数据的实时性和可靠性,但可能导致性能下降,因为它避免了缓存的延迟写入。

8. 数据块分配

在文件写入时,如果文件增长(比如追加内容或创建新文件),文件系统会分配新的数据块用于存储这些新数据。文件系统会根据需要选择合适的空闲块,并在inode中更新相应的数据块指针。

9. 写回(Flush)机制

Linux内核有专门的内存管理机制负责将脏页写回磁盘。这些机制通常是异步的,内核会在内存中脏页达到一定数量或者定时触发写回时,将脏页批量写入磁盘。常见的写回触发条件包括:

  • 内存中的脏页达到上限
  • 定时器触发(通常每隔几秒触发一次写回操作)
  • 系统调用如fsync()强制要求写回

写回操作由内核的pdflushwriteback进程负责,确保文件系统和磁盘上的数据一致性。

10. 元数据更新

在写入数据的同时,文件系统需要更新文件的元数据(如文件大小、修改时间等)。这些元数据通常保存在inode中。内核会确保在数据写回到磁盘时,也将相应的inode信息写入磁盘。

11. 文件关闭

当文件写入操作完成后,用户程序调用close()系统调用,关闭文件描述符。关闭操作不会立即强制写入所有数据到磁盘,除非fsync()被显式调用。文件关闭时,内核会释放与该文件相关的缓存和资源。

总结

文件写入过程大致如下:

  • 用户程序通过write()发起写入操作
  • 内核通过VFS和文件系统检查权限并解析路径
  • 数据被写入到Page Cache,标记为脏页
  • 数据块分配用于保存新增数据
  • 内核异步将脏页写回磁盘,或在fsync()等调用下同步写入
  • 文件元数据(如大小、修改时间)更新
  • 关闭文件描述符,释放资源

通过缓存机制,Linux能够有效提高写入性能,但也需要通过同步机制(如fsync)确保数据的持久化和一致性。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识Linux · 重定向和缓冲区

目录 前言: 预备知识 缓冲区 重定向 前言: 其实有了文件2的预备知识,我们已经初步了解了文件描述符fd是什么,底层是如何运作的了,那么本文,我们通过文件描述符对重定向和缓冲区有一个更深层次的理解&a…

JVM(HotSpot):GC之垃圾标记阶段

文章目录 前言一、标记阶段算法1、引用计数法2、可达性分析算法(JVM使用) 二、4种引用1、 强引用2、软引用(SoftReference)3、弱引用(WeakHashMap)4、虚引用(PhantomReference) 三、代码案例1、 强引用2、软引用(SoftReference)3、弱引用(WeakHashMap) 前…

AI-Talk开发板之shell_xtts

一、说明 运行duomotai_ap sdk下的shell_xtts例程,测试语音合成以及SPK功能。 操作说明:开发指南 | 聆思文档中心 (listenai.com) 与处理器的信号连接: 二、工程 1、设备树 由于AI-Talk开发板与CSK6-MIX开发板有些管脚不一样,所…

主机加固是什么?又该如何实施呢?

MCK主机加固:企业数据安全的守护神 内核级安全加固:MCK主机加固采用基于操作系统内核级的安全加固技术,从根本上阻断了病毒和恶意软件的入侵路径,确保企业核心数据的安全。 智能防御机制:智能识别并预警潜在的安全威胁…

纯血鸿蒙!

纯血鸿蒙,这是哪个营销大师给起的名字啊! 纯血!象征着高贵、自信、自主、血性、英雄气概,都融入这纯血鸿蒙了! 鸿蒙本就是开天辟地,加上纯血,真是荡气回肠! 鸿蒙的推出背景 我们前…

数据结构(JAVA)包装类泛型

文章目录 包装类基本数据类型和对应的包装类装箱和拆箱面试题 泛型什么是泛型泛型的语法泛型类的使用泛型的使用裸类型(Raw Type) (仅需了解)擦除机制泛型的上界泛型方法 包装类 基本数据类型和对应的包装类 注意,除了int基本数据类型的包装…

机器学习核心:监督学习与无监督学习

个人主页:chian-ocean 文章专栏 监督学习与无监督学习:深度解析 机器学习是现代人工智能的核心支柱,已广泛应用于从数据挖掘到计算机视觉再到自然语言处理的诸多领域。作为机器学习最主要的两大类型,监督学习(Super…

LLM - 配置 ModelScope SWIFT 测试 Qwen2-VL 视频微调(LoRA) 教程(3)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142882496 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 SWIFT …

【Neo4j】- 轻松入门图数据库

文章目录 前言-场景一、Neo4j概述二、软件安装部署1.软件下载2.软件部署3.软件使用4.语法学习 总结 前言-场景 这里用大家都了解的关系数据与图数据据库对比着说,更加方便大家理解图数据库的作用 图形数据库和关系数据库均存储信息并表示数据之间的关系。但是,关系…

【Golang】Go语言web框架Gin响应客户端有哪些方式

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Navigation2 算法流程

转自 https://zhuanlan.zhihu.com/p/405670882 此文仅作学习笔记 启动流程 在仿真环境中启动导航包的示例程序,执行nav2_bringup/bringup/launch/tb3_simulation_launch.py文件。ROS2的launch文件支持采用python语言来编写以支持更加复杂的功能,本文件…

个人用操作系统笔记(待补充)

文章目录 一、绪论二、Linux操作系统进程线程(进程内的基本调度单位)文件与设备文件权限文件系统文件连接(共享) 地址空间缺页中断 用户超级用户root(用户标识与组标识都是0) 重定向系统启动常用命令 OS研究…

【优选算法篇】踏入算法的深邃乐章:滑动窗口的极致探秘

文章目录 C 滑动窗口详解:进阶题解与思维分析前言第二章:进阶挑战2.1 水果成篮解法一:滑动窗口解法二:滑动窗口 数组模拟哈希表复杂度分析:图解分析:示例:滑动窗口执行过程图解: 详…

ARM嵌入式学习--第三天

ARM常用伪指令分析 ARM伪指令:为了方便程序员使用,编译器设计的指令,这个指令ARM核无法识别,需要编译器对它翻译成ARM核所识别的指令 -LDR R1,0xabcdef分析 总结: 编译器在编译的时候,将ldr r…

深入拆解TomcatJetty(一)

深入拆解Tomcat&Jetty(一) 专栏地址:https://time.geekbang.org/column/intro/100027701 1、Web容器是什么 早期的 Web 应用主要用于浏览新闻等静态页面,HTTP 服务器(比如 Apache、Nginx)向浏览器返…

008、相交链表

0、题目描述 相交链表 1、法1 嵌套循环,从listA的第一个节点开始与listB的每个节点比对,有相同的就返回这个节点。 时间复杂度是n^2 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* pa …

多媒体(1)

多媒体 多媒体的信息结构是【非线性的网状结构】 多媒体技术的基本特征:集成性、交互性、实时性、数字化、多样性 多媒体数据具有【数据量大】、【数据类型多】、【数据类型间区别小】、【输入输 出复杂】的特点 在多媒体数据库中,基于内容检索的关键技术…

智联云采 SRM2.0 testService SQL注入漏洞复现

0x01 产品简介 智联云采是一款针对企业供应链管理难题及智能化转型升级需求而设计的解决方案,针对企业供应链管理难题,及智能化转型升级需求,智联云采依托人工智能、物联网、大数据、云等技术,通过软硬件系统化方案,帮助企业实现供应商关系管理和采购线上化、移动化、智能…

【AI绘画】Midjourney进阶:引导线构图详解

博客主页: [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯什么是构图为什么Midjourney要使用构图 💯引导线构图特点使用场景提示词书写技巧测试 💯小结 💯前言 【AI绘画】Midjourney进阶&a…

嵌入式职业规划

嵌入式职业规划 在嵌入式的软件开发中,可以分为: 嵌入式MCU软件开发工程师; 嵌入式Linux底层(BSP)软件开发工程师; 嵌入式Linux应用开发工程师; 嵌入式FPGA算法开发工程师 对于前两个阶段 …