C#流Stream与IO详解(5)——读取文件的详细流程

【前言】

这里说的是阻塞式读写文件,只说主要的流程,不包括每个流程中为了处理不同情况的更细节处理

【读取文件】

  • 应用程序中(用户层)
    • C#调用FileStream.Read相关接口,传递文件句柄FileHandle,要读取的数据大小count,数据需要放在哪array startIndex等参数到C接口的ReadFile函数
    • C函数中发起系统调用,即调用库函数read() (系统调用的简单理解:操作系统是应用程序的管理者,系统调用是操作系统提供给该程序的通信接口,类似我们常写的对象Manager给对象实例提供的接口一样)
  • 系统调用(进入内核层)
    • CPU软中断:CPU在运行应用程序,执行代码,然后执行到读文件的代码时,发现这是一个系统调用函数,且是读取文件的IO操作,于是发生软中断。CPU保存当前进程信息,运行其他进程。
      • 如果没有中断,那么CPU需要轮询IO设备状态,一直等待IO设备完成读数据的请求,CPU在这段时间内什么也干不了,是对CPU资源的巨大浪费
      • 虽然CPU切换进程也会消耗一定的时间,这相比对等待一般IO设备完成请求而言要小得多
      • 一般来说CPU的速度比IO设备高几个数量级,但如果有个快速IO设备,那么CPU中断和切换进程的时间可能比轮询还多,所以CPU中断不一定比轮询好。在编程时要避免短时间内出现大量IO请求,否则CPU会不断中断,使得操作系统过载并引发活锁。
      • 在网络场景中一般不会使用中断,因为会在短时间内收到大量网络包,中断会导致活锁
    • 虚拟文件系统VFS:文件系统有很多实现,虚拟文件系统是一个抽象的文件系统模型,提供一个通用的接口,操作系统只需要调用接口即可,不需要关心文件系统的具体实现。类似于我们编程常写的基类。
    • 页缓存Page Cache:如果要读取的数据刚好在页缓存中存在,那么把数据从内核态拷贝到用户进程的内存中
    • 文件系统:文件系统提供了VFS的具体实现,如果页缓存中没有要读取的数据,那么就会调用到文件系统对read接口的具体实现
    • 通过块管理层:通用块层提供一个统一的接口供文件系统实现者使用,而不用关心不同设备驱动程序的差异,这样实现出来的文件系统就能用于任何的块设备。通过对设备进行抽象后,不管是磁盘还是机械硬盘,对于文件系统都可以使用相同的接口对逻辑数据块进行读写操作。通用块层会发出一个IO调度请求
    • IO调度层:对通用块层发出的IO调度请求,不一定会立即执行。其他应用程序也可能在不久前发出IO调度请求,这些IO调度请求会被缓存起来,在操作系统认为合适的时机,统一发出IO调度请求。什么时候是合适的时机,这就是IO调度算法要解决的问题,常见的调度算法有先来先服务(FCFS)、最短寻道时间优先(SSTF)、电梯算法等。
    • 设备驱动程序:操作系统需要完成和硬件设备的交互,负责这部分功能的是设备驱动程序。操作系统提供标准接口,设备的生产厂商负责编写设备驱动的具体实现。进而使得操作系统可以兼容不同厂商生产的相同功能的设备而无需关心具体实现细节。因此,插入系统的设备都会先经过安装驱动程序的步骤。我们知道接口有个通用的缺点,即无法使用接口实现者的特殊功能,因为接口本质是为抽象多数而不是全部。例如,在编程上,子类如果非常多,总会有个子类有个特殊方法,而大多数子类没有,这个方法无法暴露在接口上给接口调用者使用。在硬件上就体现为,某个设备有个特殊的功能,但操作系统无法使用。对文件系统而言,这里的驱动程序是磁盘驱动程序。
  • 硬件层
    • 找到数据所在的扇区编号
      • 磁盘包括硬盘,硬盘分为机械硬盘HDD和固态硬盘SSD。磁盘有一定数量的扇区,有n个扇区的磁盘上,编号为0到n-1,这也是磁盘的地址空间。
      • 一般一个扇区的内存大小时512块,制造商保证单个512字节的读写是原子的,即要么完整的读写完成,要么不会完成,不存在其他可能。而一般操作系统一次读写的大小为4kb(或者更多)
    • 磁盘驱动器会根据要读取的扇区编号找到数据所在的磁道
      • 扇区编号与具体的磁道是由固定的映射关系的,知道数据在哪个扇区,磁盘驱动器就可以知道数据在哪个磁道。但还需要将磁盘臂移动到该磁道才能读取数据,这就是一个寻道seek过程。如果数据在不同的磁道,那么就需要在多个磁道间切换。因此,存在一个寻道时间。
      • 一个磁道上由多个扇区,磁盘臂移动到磁道上后需要等待盘片旋转到某个扇区才能读数据,因此存在一个旋转时间
    • 磁头读写数据

【更细节的详细过程】

中断过程:

  • 硬件会提供不同的执行模式来协助操作系统,在用户态下,应用程序不能完全访问硬件资源,在内核态下,操作系统可以访问机器的全部资源。还提供了陷入内核和从陷进返回用户态的指令。
  • 系统调用有明确的调用约定,参数返回值都要放到什么寄存器内,执行那条陷入指令,这需要用汇编手工编码
  • 当机器启动时,操作系统会设置陷阱表trap table,其作用是建立了陷入指令和陷入处理程序的映射关系,操作系统通过某种特殊指令告知硬件陷入处理程序的位置。这一切都是在内核态下完成的
  • 发送中断时,操作系统获取CPU的控制权,当前进程变成阻塞状态(数据读取完成后变成就绪状态)。操作系统通过调度算法确定接下来要运行的进程,随后通过陷入返回指令回到用户态。
  • 如果没有系统调用引起的中断,发生时钟中断时,操作系统也会获取CPU的控制权。

内存与设备交互:

  • DMA(Direct Memory Access):内存和设备之间需要数据传递,原来这部分是由CPU完成了,为了提高效率,这件事交给DMA完成。
    • 读数据时:操作系统告诉DMA,读取的数据存放的起始地址,大小,在哪个设备读取。
    • 当DMA任务完成后,会抛出一个中断请求,告诉操作系统,数据传输的任务完成了。
  • 交互方式:
    • 特权指令:这些指令规定了操作系统将数据发送到特定设备寄存器的方法,这些方法规定了双方交互的协议
    • 内存映射I/O:硬件将设备寄存器作为内存地址提供,当需要访问设备寄存器时,操作系统读取或写入到该内存地址

如何找到扇区:

  • 文件系统会记录每个文件的信息,信息包括文件的大小、文件数据位于哪些数据块中(即扇区中)、文件所有者、访问权限、访问和修改时间等信息。这些信息在一个inode数据结构中。
  • 所有文件的inode信息也要保存在磁盘上,每个文件和文件夹都有一个inode编号(inumber),可以通过inumber拿到inode信息,这构成一个inode table,其在文件系统初始化时就从磁盘加载到内存中。文件系统初始化一般是在操作系统启动也即开机的时候进行。
  • 文件夹也有对应的inode,其包含(文件夹名或者文件名,inumber)列表,可以找到文件夹(即目录)下的文件夹及文件,其构成一个目录树
  • 当打开一个文件时,会根据传入的路径以及目录树递归找到该文件的inumber,从inode table中找到该文件的inode信息。
  • 打开文件时会创建一个file对象的数据结构,这个数据结构中会保存要读取的文件的inumber,同时返回一个文件描述符file descriptor(在windows中也叫文件句柄file handle)
  • 读取文件时根据文件句柄找到file对象,找到文件的inumber,扎到文件inode,根据要传入的StartIndex和length,找到要读取哪些扇区的数据
  • 在多进程中,为了不同进程共用file对象,会多包装一层。每个进程有文件描述符和描述符表,多个进程共享一个文件表,描述符表指向文件表中的某个file对象。

【参考】 

《操作系统导论》

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

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

相关文章

数据分析:数据预处理流程及方法

数据预处理是数据分析过程中至关重要的一步,它涉及到清洗、转换和整理原始数据,以便更好地适应分析模型或算法。以下是一些常见的数据预处理方法和规则: 数据清洗: 处理缺失值:检测并处理数据中的缺失值,可…

武汉凯迪正大—盐雾试验机

产品概述 武汉凯迪正大KDYD-YW盐雾试验箱乃针对各种材质表面处理,包含涂料、电镀、有机及无机皮膜,阳极处理,防锈油等防腐处理后测试其耐腐蚀性,从而确立产品的质量。 产品特点 1、结构紧凑,体积小、携带方便&#…

.NET中的Object类学习3_MemberwiseClone方法

文章目录 一、前言二、Object.MemberwiseClone方法1 定义2 示例3 备注 三、总结 一、前言 按照MSDN文档的章节顺序来,本文应该是第五节。 但是学了上一节 Finalize之后,发现其内容对实际开发帮助不大。 所以这次跳过了前面的GetHashCode、GetType章节&a…

艺术作品3D虚拟云展厅能让客户远程身临其境地欣赏美

艺术品由于货物昂贵、易碎且保存难度大,因此在艺术品售卖中极易受时空限制,艺术品三维云展平台在线制作是基于web端将艺术品的图文、模型及视频等资料进行上传搭配,构建一个线上艺术品3D虚拟展厅,为艺术家和观众提供了全新的展示和…

opencv-python 印刷质量缺陷的视觉检测

Windows10PythonYolov8ONNX图片缺陷识别,并在原图中标记缺陷,有onnx模型则无需配置,无需训练。 ** PythonYolov8ONNX实时缺陷目标检测原文 labelimg使用指南 windows使用YOLOv8训练自己的模型(0基础保姆级教学) pyth…

Chrome和chromedriver版本不匹配导致的UI自动化测试无法运行的问题

今天,遇到一个小问题,本来跑的好好UI自动化测试脚本突然不好使了,期初怀疑是页面元素有调整导致脚本出现异常无法正常执行,经排查后发现近期页面没有任何调整。 这下头大了,啥也没改,怎么好好的脚本不能跑…

Vue3鼠标拖拽生成区域块并选中元素

Vue3鼠标拖拽生成区域块并选中元素&#xff0c;选中的元素则背景高亮(或者其它逻辑)。 <script setup> import { ref } from vue// 区域ref const regionRef ref(null)// 内容ref const itemRefs ref(null)// 是否开启绘画区域 const enable ref(false)// 鼠标开始位置…

vite打包vue2 history路由模式的的项目部署线上后<router-view />页面显示空白,命令行也不报错,本地是没有问题的

如题&#xff0c;本地畅通无阻&#xff0c;但是部署到服务器上就无法访问&#xff0c;本地是localhost://login可以访问到&#xff0c;但是因为我这里所有前端项目有一个路由映射&#xff0c;相当于是一个二级路由&#xff0c;导致线上路由出错&#xff0c;所以给路由加一个bas…

LVS+keepalived——高可用集群

lvskeepalived&#xff1a;高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。但是&#xff1a;keepalived不是专门为lvs集群服务的&#xff0c;也可以做其他代理服务器的高可用。 lvs的…

基于SSM的进销存管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Vue typescript项目配置eslint+prettier

1.安装依赖 安装 eslint yarn add eslint --dev安装 eslint-plugin-vue yarn add eslint-plugin-vue --dev主要用于检查 Vue 文件语法 安装 prettier 及相关插件 yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev安装 typescript 解析器、规则补充 …

Spring-IOC-@Import的用法

1、Car.java package com.atguigu.ioc; import lombok.Data; Data public class Car {private String cname; }2、 MySpringConfiguration2.java package com.atguigu.ioc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…

树莓派的的串口通信协议

首先&#xff0c;回顾一下串口的核心知识点&#xff0c;也是面试重点&#xff1a; 串口通信通常使用在多机通讯中串口通信是全双工的决定串口通信的成功与否的是 数据格式 和 波特率数据格式&#xff1a;1. 数据位 2.停止位 3. 奇偶校验位 树莓派恢复串口 回忆前几节树莓派刷机…

Vue3 配置全局 scss 变量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css变量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

AI大发展:人机交互、智能生活全解析

目录 ​编辑 人工智能对我们的生活影响有多大 人工智能的应用领域 一、机器学习与深度学习 二、计算机视觉 三、自然语言处理 四、机器人技术 五、智能推荐系统 六、智能城市和智能家居 ​编辑 自己对人工智能的应用 自己的人工智能看法&#xff1a;以ChatGPT为例 …

watcheffect的用法

需求&#xff1a;监听用户给金额字段改大了还是改小了 let previousAmount: number | null null; watchEffect(() > {for (let i 0; i < projectList.value.length; i) {const currentAmount Number(projectList.value[i].je);if (previousAmount ! null) { //不是空…

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…

BE节点经常挂掉:[IO_ERROR]failed to list /proc/27349/fd/: No such file or directory

最近BE节点经常挂掉 Caused by: java.lang.RuntimeException: Failed to execute internal SQL. org.apache.doris.common.UserException: errCode 2, detailMessage There is no scanNode Backend available.[10031: not alive] OriginStatement{originStmtSELECT * FROM _…

分布式任务调度-XXL-job

目录 源码仓库地址 前置环境 docker容器环境配置 连接linux数据库&#xff0c;并创建任务调度所用到的数据库xxl-job。 用到的表sql 打开映射网址 后端配置使用任务调度 依赖 yml配置 使用架构 config配置 job使用 快速入门使用 任务调度执行器 任务调度执行管理​编…

ck 配置 clickhouse-jdbc-bridge

背景 ck可以用过clickhouse-jdbc-bridge技术来直接访问各数据库 安装配置 需要准备的文件 clickhouse-jdbc-bridge https://github.com/ClickHouse/clickhouse-jdbc-bridge 理论上需要下载源码然后用mavne打包&#xff0c;但提供了打包好的&#xff0c;可以推测用的是mave…