Linux文件IO(三)-Linux系统如何管理文件

news2024/12/29 10:54:40

1.静态文件与 inode

文件在没有被打开的情况下一般都是存放在磁盘中的,譬如电脑硬盘、移动硬盘、U 盘等外部存储设备,文件存放在磁盘文件系统中,并且以一种固定的形式进行存放,我们把他们称为静态文件

文件储存在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector),每个扇区储存 512 字节(相当于 0.5KB),操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取的最小单位。“块”的大小,最常见的是 4KB,即连续八个 sector 组成一个 block。

所以由此可以知道,静态文件对应的数据都是存储在磁盘设备不同的“块”中,那么问题来了,我们在程序中调用 open 函数是如何找到对应文件的数据存储“块”的呢,难道仅仅通过指定的文件路径就可以实现?这里我们就来简单地聊一聊这内部实现的过程。

我们的磁盘在进行分区、格式化的时候会将其分为两个区域,一个是数据区,用于存储文件中的数据;另一个是 inode 区,用于存放 inode table(inode 表),inode table 中存放的是一个一个的 inode(也成为 inode节点),不同的 inode 就可以表示不同的文件,每一个文件都必须对应一个 inode,inode 实质上是一个结构体,这个结构体中有很多的元素,不同的元素记录了文件了不同信息,譬如文件字节大小、文件所有者、文件对应的读/写/执行权限、文件时间戳(创建时间、更新时间等)、文件类型、文件数据存储的 block(块)位置等等信息。

所以由此可知,inode table 表本身也需要占用磁盘的存储空间。每一个文件都有唯一的一个 inode,每一个 inode 都有一个与之相对应的数字编号,通过这个数字编号就可以找到 inode table 中所对应的 inode。

在 Linux 系统下,我们可以通过"ls -i"命令查看文件的 inode 编号,如下所示:

上图中 ls 打印出来的信息中,每一行前面的一个数字就表示了对应文件的 inode 编号。除此之外,还可以使用 stat 命令查看,用法如下:

由以上的介绍大家可以联系到实际操作中,譬如我们在 Windows 下进行 U 盘格式化的时候会有一个“快速格式化”选项,如下所示:

如果勾选了“快速格式化”选项,在进行格式化操作的时候非常的快,而如果不勾选此选项,直接使用普通格式化方式,将会比较慢,那说明这两种格式化方式是存在差异的,其实快速格式化只是删除了 U 盘中的 inode table 表,真正存储文件数据的区域并没有动,所以使用快速格式化的 U 盘,其中的数据是可以被找回来的。

通过以上介绍可知,打开一个文件,系统内部会将这个过程分为三步:

  1. 系统找到这个文件名所对应的 inode 编号;

  2. 通过 inode 编号从 inode table 中找到对应的 inode 结构体;

  3. 根据 inode 结构体中记录的信息,确定文件数据所在的 block,并读出数据。

2.文件打开时的状态

当我们调用 open 函数去打开文件的时候,内核会申请一段内存(一段缓冲区),并且将静态文件的数据内容从磁盘这些存储设备中读取到内存中进行管理、缓存(也把内存中的这份文件数据叫做动态文件、内核缓冲区)。打开文件后,以后对这个文件的读写操作,都是针对内存中这一份动态文件进行相关的操作,而并不是针对磁盘中存放的静态文件。

当我们对动态文件进行读写操作后,此时内存中的动态文件和磁盘设备中的静态文件就不同步了,数据的同步工作由内核完成,内核会在之后将内存这份动态文件更新(同步)到磁盘设备中。由此我们也可以联系到实际操作中,譬如说:

  • 打开一个大文件的时候会比较慢;
  • 文档写了一半,没记得保存,此时电脑因为突然停电直接掉电关机了,当重启电脑后,打开编写的文档,发现之前写的内容已经丢失。

想必各位读者在工作当中都遇到过这种问题吧,通过上面的介绍,就解释了为什么会出现这种问题。好,我们再来说一下,为什么要这样设计?

因为磁盘、硬盘、U 盘等存储设备基本都是 Flash 块设备,因为块设备硬件本身有读写限制等特征,块设备是以一块一块为单位进行读写的(一个块包含多个扇区,而一个扇区包含多个字节),一个字节的改动也需要将该字节所在的 block 全部读取出来进行修改,修改完成之后再写入块设备中,所以导致对块设备的读写操作非常不灵活;而内存可以按字节为单位来操作,而且可以随机操作任意地址数据,非常地很灵活,所以对于操作系统来说,会先将磁盘中的静态文件读取到内存中进行缓存,读写操作都是针对这份动态文件,而不是直接去操作磁盘中的静态文件,不但操作不灵活,效率也会下降很多,因为内存的读写速率远比磁盘读写快得多。

在 Linux 系统中,内核会为每个进程(关于进程的概念,这是后面的内容,我们可以简单地理解为一个运行的程序就是一个进程,运行了多个程序那就是存在多个进程)设置一个专门的数据结构用于管理该进程,譬如用于记录进程的状态信息、运行特征等,我们把这个称为进程控制块(Process control block,缩写PCB)。

PCB 数据结构体中有一个指针指向了文件描述符表(File descriptors),文件描述符表中的每一个元素索引到对应的文件表(File table),文件表也是一个数据结构体,其中记录了很多文件相关的信息,譬如文件状态标志、引用计数、当前文件的读写偏移量以及 inode 指针(指向该文件对应的 inode)等,进程打开的所有文件对应的文件描述符都记录在文件描述符表中,每一个文件描述符都会指向一个对应的文件表,其示意图如下所示:

前面给大家介绍了 inode,inode 数据结构体中的元素会记录该文件的数据存储的 block(块),也就是说可以通过 inode 找到文件数据存在在磁盘设备中的那个位置,从而把文件数据读取出来。

以上就是给大家介绍到所有内容了,上面给大家所介绍的内容后面的学习过程中还会用到,虽然这些理论知识对大家的编程并没有什么影响,但是会帮助大家理解文件 IO 背后隐藏的一些理论知识,其实这些理论知识还是非常浅薄的、只是一个大概的认识,其内部具体的实现是比较复杂的,当然这个不是我们学习 Linux 应用编程的重点,操作系统已经帮我们完成了这些具体的实现,我们要做的仅仅只是调用操作系统提供 API 函数来完成自己的工作。

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

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

相关文章

[000-002-01].第29节:MySQL执行流程

1、MySQL的查询流程: 客户端请求进入到数据库服务器后,先进行查询缓存,如果命中,那么就返回结果;如果没命中,进入到解析器,进行词法解析和语法解析,生成解析树;然后进入到…

Python在AI中的应用--使用决策树进行文本分类

Python在AI中的应用--使用决策树进行文本分类 文本分类决策树什么是决策树 scikit算法 使用scikit的决策树进行文章分类一个文本分类的Python代码使用的scikit APIs说明装入数据集决策树算法类类构造器: 构造决策树分类器产生输出评估输出结果分类准确度分类文字评估…

langchain介绍以及简单实用

1,介绍 LangChain是一个用于开发由大语言模型支持的应用程序的框架。它提供了大量组件来帮助我们构建LLM支持的应用程序。 其主要是有六大功能组成。 LLMs(大语言模型(生成式语言模型)),Prompts(提示词),Memory(记忆力)&#xff…

电器行业文件加密怎么做?防泄密哪种方法实用?

管控需求 1.电子文档(源代码、设计图纸、设计方案等)数据不同应用场景下如何有效保护; 2.发给第三方或外部单位的成果数据没有任何限制,对方可拷贝、篡改、截屏、盗用,严重损害单位的利益; 3.对员工出差…

基于单片机巡迹避障智能小车系统

文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…

[Python学习日记-28] 开发基础练习1——股票查询程序

[Python学习日记-28] 开发基础练习1——股票查询程序 简介 题目及效果参考 源码与解析 简介 该练习使用了列表、字典、字符串等之前学到的数据类型,用于巩固实践之前学习的内容,题目当中使用到的数据均摘录与东方财富网,最好在学习完前面的…

【论文阅读】Grounding Language with Visual Affordances over Unstructured Data

Abstract 最近的研究表明,大型语言模型(llms)可以应用于将自然语言应用于各种各样的机器人技能。然而,在实践中,学习多任务、语言条件机器人技能通常需要大规模的数据收集和频繁的人为干预来重置环境或帮助纠正当前的…

USB总线同步数据采集卡6路高速模拟量采集带DIO功能USB2884/2885/2886

USB2884/2885/2886 数据采集卡 概述: 系统框图: 规格参数: 板卡外形图: 尺寸图及元器件功能说明:

图像识别OCR(Tess4J)

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

ZBrush入门使用介绍——16、ArrayMesh

大家好,我是阿赵。   继续介绍ZBrush的用法。这次看看ArrayMesh功能。   简单来说,ArrayMesh功能是可以复制很多个模型,然后根据路径排列。 一、 从阵列预设生成ArrayMesh 先把模型转换成多边形网格体 这时候,ArrayMesh的选…

jupyter安装与使用——Ubuntu服务器

jupyter安装与使用——Ubuntu服务器 一、安装miniconda3/anaconda31. 下载miniconda32. 安装miniconda33. 切换到bin文件夹4. 输入pwd获取路径5. 打开用户环境编辑页面6. 重新加载用户环境变量7. 初始化conda8.验证是否安装成功9.conda配置 二、安装jupyter2.1 conda安装2.2 配…

Java调用数据库 笔记05(查询篇)

一. 数据库(通过各种驱动来实现调用): (应用程序通过接口控制的各种数据库驱动来调用数据库-->jdbc方法) 1.创建Java的普通class类 2.加载驱动 Class.forName("com.mysql.jdbc.Driver"); 3.驱动管理类…

C++_23_STL容器

文章目录 STL容器概念常用容器A string作用构造函数基本赋值操作获取字符串长度存取字符操作拼接操作查找和替换注意:查找是不存在返回-1比较操作截取操作插入与删除string与char * 转换 B vector概述与数组区别迭代器构造函数赋值操作插入与删除取值操作大小相关存储自定义类型…

linux 安装 tomcat9、java环境

一、安装 Java环境 1. 下载文件 https://repo.huaweicloud.com/java/jdk/ 或者网盘:通过网盘分享的文件:jdk-8u192-linux-x64.tar.gz 链接: https://pan.baidu.com/s/1V3pQWzgSLJxdrUdmmKueRA 提取码: qspw 2. 查看Linux系统是否有自带的jdk&#xf…

智慧水利采砂船在线监控平台:构建高效、智能的河道采砂监管体系

随着科技的不断发展,水利行业的智慧化转型也日益受到重视。智慧水利采砂船在线监控平台便是这一转型的重要成果之一。该平台主要服务于水政执法人员,针对取得河道采砂许可证的采砂公司及采砂船,实施在线自动监控,旨在提高监管效率…

评论表设计与实现(多级评论)

首先分析评论的类型 对文章的回复(也称根回复或一级回复)对根评论的回复 (二级回复,被回复的评论id和根评论相同)对回复的回复(二级回复,被回复的评论id和根评论不同) 抽象出数据库…

if __name__ == ‘__main__‘: 在 Python 中的作用

Python Python 是一种广泛使用的高级编程语言,它以其易读性和简洁的语法而闻名。Python 支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。它由 Guido van Rossum 创建,并在 1991 年首次发布。 Python 的一些关键特性包括&#…

MacOS Catalina 从源码构建Qt6.2开发库之02: 配置QtCreator

安装Qt-creator-5.0.2 在option命令中配置Qt Versions指向 /usr/local/bin/qmake6 Kits选入CLang

解决银河麒麟桌面操作系统V10SP1 SSH连接“connection reset by ip地址 port 22”问题

解决银河麒麟桌面操作系统V10SP1 SSH连接“connection reset by ip地址 port 22”问题 💖The Begin💖点点关注,收藏不迷路💖 遇到SSH连接银河麒麟V10SP1时“connection reset by ip地址 port 22”的错误,可以尝试以下步…

GNU链接器(LD):设置入口点(ENTRY命令)的用法及实例解析

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分: (1)编译器 (2)汇编器 (3)链接器 (4)lib库 在GNU工具链中&…