首页 > 系统相关 >Linux中文件的读写过程

Linux中文件的读写过程

时间:2024-10-18 10:17:04浏览次数:10  
标签:文件 读取 读写 写入 内核 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)确保数据的持久化和一致性。

标签:文件,读取,读写,写入,内核,Linux,磁盘,数据
From: https://blog.csdn.net/zyqash/article/details/143036100

相关文章

  • Linux驱动开发 platform设备注册详解
    常用的与平台设备注册相关的函数及其作用:1.platform_device_register()功能:用于注册平台设备到内核设备模型中。注册后,设备与相应的驱动程序绑定,驱动的probe函数被调用以进行初始化。函数原型:intplatform_device_register(structplatform_device*pdev);参数:pde......
  • python文件操作
    1.文件的编码思考:计算机只能识别:0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢?答案:使用编码技术(密码本)将内容翻译成0和1存入。计算机只认识0和1,所以需要将内容翻译成0和1才能保存在计算机中,同时也需要编码,将计算机保存的0和1,反向翻译回可以识别的内容不......
  • 医疗行业文件同步管理,如何保障准确性和高效性双管齐下?
    医院、诊所、制药公司等医疗行业企业需要管理患者的健康记录、病历、药物研发数据等敏感信息。这些数据的丢失可能导致严重的法律后果和声誉损失,因此文件同步备份是必须的。常用的文件同步方式有以下几种:云存储服务:云存储服务是最简单的文件同步方式之一。用户可以选择云存储服......
  • 【Linux线程】Linux多线程编程:深入理解线程互斥与同步机制
    ......
  • [Redis] 在Linux中安装Redis并连接图形化工具详细过程(附下载链接)
    前言安装Redis之前应该在虚拟机中安装Linux系统,这里使用centos7版本[linux]在VMware中安装linux、文件下载及详细安装过程(附下载链接)-CSDN博客安装Linux后,更换yum源为阿里云并安装gcc依赖[Linux]CentOS7替换yum源为阿里云并安装gcc详细过程(附下载链接)-CSDN博客redis-6......
  • ctfshow(78->81)--文件包含漏洞
    Web78源代码如下:if(isset($_GET['file'])){$file=$_GET['file'];include($file);}else{highlight_file(__FILE__);代码审计:使用include()进行文件包含,通过GET方法传递参数file获取被包含的文件。思路:利用data://伪协议,执行系统命令,获取flag......
  • linux ps和kill指令
    目录ps命令kill指令:示例:补充:管道的概念管道的概念管道的用途示例在Linux系统中,ps和kill是两个非常常用的命令,用于管理和终止进程。ps命令ps命令用于显示当前系统中的进程状态。它可以提供关于系统进程的详细信息,如进程ID、运行用户、CPU使用率、内存使用......
  • 公网Linux环境搭建frp实现内网穿透
    前提:本实验为一台ubuntu22操作系统云主机脚本适用于安装平台:CentOS、Debian、UbuntuFRP项目地址:https://github.com/fatedier/frpFRP一键脚本地址:https://github.com/MvsCode/frps-onekey 1、FRP服务器端一键安装脚本(脚本在本文最后有,如果在服务器上无法获取到下面的instal......
  • Linux环境下Matplotlib绘图中文乱码问题
    问题:如图所示,中文乱码1.准备ttf字体文件:路径: C:\Windows\Fonts例如楷体:simkai.ttf2.查看当前环境的matplot字体路径:importmatplotlibprint(matplotlib.matplotlib_fname())运行结果:/home/3kyou/.local/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibr......
  • 使用vs2022将.net8的应用程序发布为一个单独文件
    在使用.NetCore3.1时,可以通过设置以下工程配置文本来将项目发布为一个单独的应用程序文件:<ProjectSdk="Microsoft.NET.Sdk.WindowsDesktop"><PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework><UseWPF>true</UseWPF> <Publi......