Linux中文件的理解
✨前言✨
📘 博客主页:to Keep博客主页
🙆欢迎关注,👍点赞,📝留言评论
⏳首发时间:2024年10月16日
📨 博主码云地址:渣渣C
📕参考书籍:C语言程序与设计 和 数据结构(C语言版)
📢编程练习:牛客网+力扣网
Linux中文件的理解
- 一 系统调用接口
- 1 open函数(打开操作)
- 1.1 flag标志位
- 1.2 文件权限
- 2 write函数(写入操作)
- 3 read函数(读取文件)
- 4 close函数(关闭文件)
- 5 文件描述符
- 6 dup2函数(重定向)
- 二 缓冲区
- 三 文件系统
- 四 软硬链接
~~~~~~~~ 对于文件我们都知道,文件=文件内容+文件属性!我们都知道要对文件进行操作,我们第一步就是要打开文件,根据我们之前提及的冯诺依曼体系结构,该文件就必须加载到内存当中,也就是说是对应的进程打开文件的,而文件我们一般可以分为两种,一种就是被加载到内存中的,一种是位于磁盘上的!我们先来学习内存文件,在C语言中,也提供了一系列的库函数来对文件进行操作!
读写操作
打开操作
关闭操作
我们主要介绍以下三种打开文件的模式:
以w方式打开文件时候,在对文件进行写入操作的时候,是会覆盖掉原文件有的内容的,相当于我们之前说过的重定向!而使用a方式打开文件,在对文件写入操作就可以在原文件有内容的基础上增加内容的,也就是我们所说的追加重定向!
一 系统调用接口
实际上,C语言层面上的一系列对文件的操作函数底层其实都是封装了系统调用函数,来针对文件进行操作!
1 open函数(打开操作)
pathname:指的就是文件所在的路径(通常就是以绝对路径给出,如果设置了对应的环境变量,也可以相对路径),默认就是我们当前进程创建时的路径!
flag:是一个标志位,可以用来标识我们打开文件的模式,下面会详细介绍!
mode:创建文件时,给文件设置的权限
返回值:文件描述符
1.1 flag标志位
实际上,标志位就是一个位图,用32位来标识不同的模式,如下图所示:
原理如下图所示,通过与操作,确定哪一个模式,然后执行对应的功能!
1.2 文件权限
在使用open函数的时候,如果对权限不做处理就创建文件,那么文件的权限就会乱掉,我们就来复习一下Linux中的权限,在Linux中的权限中,我们就知道,目录的默认权限是777,文件的默认权限是666!而我们Linux系统中默认的权限掩码是002,所以就可以得到下表的内容:
计算规则为:最终权限=默认权限 & (~umask)
在使用open函数,如果我们对文件掩码不进行设置,那么文件的权限可能就会乱掉!所以我们一般采用第二个open函数,设置自己想要的文件权限!如下图所示:
我们一般结合umask函数与自己设置的权限结合得到该文件的权限!如果不使用umask,默认就会使用Linux系统中默认的掩码!
2 write函数(写入操作)
fd:文件描述符
buf:要写入文件的内容
count:要写入内容的长度
3 read函数(读取文件)
fd:文件描述符
buf:将文件中读取的内容存放在buf中
count:选择读取的长度
4 close函数(关闭文件)
fd:文件描述符
5 文件描述符
从上述系统调用接口中的参数,我们就可以发现其实文件描述符就是一个整数!其实在C语言中,FILE是一个结构体,里面其实也必须包含文件描述符!如下图所示:
那么文件描述符既然是一个数字,哪我们怎么知道哪个数字是对应哪个文件的呢?事实上,文件加载到内存中,就会被管理起来,和我们的进程一样,用链表形式管理起来,我们会用一个文件描述符表(相当于一个数组)记录下文件所在的位置,而我们的进程就会指向这个文件描述符表!如下图所示:
而每一个文件被加载到内存中,C语言会默认的打开三个文件,那就是标准输入,标准输出,标准错误!对应的文件描述符默认值分别就是0,1,2!
6 dup2函数(重定向)
简单了解了文件描述符的原理,并且知道了在C语言中,会默认打开三个文件,这样我们就可以知道输出重定向(追加重定向)的原理了,就是利用上层C语言在标准输入,标准输出,标准错误三个文件结构体中,给文件描述符默认值就是0,1,2。那么我们利用系统调用函数(底层可以直接改变文件描述符的函数)就可以关闭标准输出这个文件,然后最新打开的文件(加载到内存中的文件)就会被文件描述符表中的1所指向了(因为文件描述符表的原则就是将最小的并且没有被使用的数组下标,会分配给最新打开的文件)!但是在C语言上层并没有改变,他的标准输出文件描述符还是在1,所以向显示器输出,转而向文件输出了!从而实现了输出重定向(输入重定向的原理也类似,就是关闭文件描述符0)!
dup2函数的原理就不用关闭这么麻烦,上述只是为了让我们更好的理解什么是重定向!dup2函数可以将一个已存在的文件描述符复制到另一个文件描述符上,并且可以自定义新文件描述符的编号。具体的可以参考dup2函数的原理,如下图所示(本来是向显示器写入的,结果向文件写入了):
二 缓冲区
从上面我们就了解到了加载到内存中的文件我们是如何操作的!并且内存中文件的本质其实就是数组下标!对我们操作过的文件是如何刷新到磁盘上的呢?这就不得不提到C语言中的缓冲区了!它本质也就是一块内存区域!为什么会要有缓冲区呢?我们都知道,调用系统调用是有系统开销的!如果我们频繁的去使用系统调用,就会导致我们的对于文件的操作效率就会下降!这是我们不希望的!这里我就简单说下缓冲区大概一个原理(如下图所示):
我们对文件操作,使用fwrite函数等,并没有立即调用系统调用函数刷新到操作系统中的缓冲区!而是要满足一定的条件!具体可以概括为以下三种情况:
1️⃣无刷新,无缓冲!直接调用底层的系统调用
2️⃣行刷新,遇到\n就刷新数据
3️⃣全缓冲,全刷新。等缓冲区满了就刷新!
当然我们也可以手动调用系统调用函数采用强制刷新,或者进程退出后会进行自动的刷新数据!一般遇到第二种或者第三种情况比较多,这就是缓冲区的一个大致原理!
三 文件系统
在了解完内存中文件的操作,以及是通过缓冲区刷新到磁盘上的!我们在来了解一下对于磁盘上的文件我们是如何管理的!实际上,磁盘上的文件就是利用文件系统来进行管理的!简单来说,就是我们操作系统会对磁盘进行分区,分区之后在进行分组,然后在对分组进行管理,从而实现对文件系统的管理!文件系统的原理图如下所示:
在介绍分组中的参数前,我们还需要了解一样东西,就是文件的inode编号,我们操作系统对于文件的增删查改都是基于这个inode编号来实现了,它在当前分区下是唯一的但是在分组里面并不是唯一的(这是因为进入分组之后,我们都要用文件的inode编号减去分组中的第一个inode编号,也就是意味着,在每一个分组中,inode bitmap中的都是从1开始计数的)!inode结构的伪代码如下所示(所占空间大小固定为128字节,该内容是保存在inode Table中的):
struct inode
{权限类型大小......inode编号int blcok[15]
}
在Xshell中我们也可以查看到文件的inode
1️⃣BootBlock:启动块,一般是在第一个分区的第一个扇区上,也就是我们C盘独有的一个数据块!
2️⃣inode Bitmap:用来标记有那些inode还没有被占用
3️⃣Block Bitmap:用来标记那些数据块是空闲的,可以放数据。
4️⃣Data Block:存放数据(也就是文件内容)。
5️⃣inode Table:存放inode有关信息(也就是文件属性)。
6️⃣Group Descriptor Table:用来标识当前组inode与数据块的空闲等的使用情况。
7️⃣Super Block:用来标识该分区的inode与数据块的空闲等的整体使用情况,并不是每一个分组都有,而是某些组里面有!
倘若我们要创建一个文件然后写入数据,我们首先就是根据操作系统给文件分配inode编号,找到它所分配到的组,然后inode bitmap找到一个空位然后改为1(表示被占用),然后根据的文件属性,初始化inode结构体,然后保存到inode table对应的位置!然后根据block bitmap找到空闲的数据块改为1,然后将文件内容写入到Data block中!如果要删除文件,那就简单了,根据inode编号将对应的文件的inode bitmap与block bitmap对应的位置置为0,表示数据可以被覆盖就表示删除了!
总的来说,对文件系统就是将Super Block加载到内存中,从而实现对磁盘上的文件管理!所以,每一个分区是可以使用不同的文件系统进行管理的!只是在Linux是采用了Super Block这种方式进行管理!
四 软硬链接
软链接命令:
ln -s 被链接文件 链接之后取的文件名字
硬链接命令:
ln 被链接文件 链接之后取的文件名字
我们在来看看,通过软硬链接之后,查看一下文件的inode编号
可以发现,软连接是新创建了一个文件,那是因为与原来的文件的inode编号不一样,而硬链接inode编号是与原先的文件一致!并且硬链接数变成了2,软链接的硬链接数还是1。这是因为软链接里面放的内容是目标文件的路径,硬链接就是在其目录文件上(因为目录也是文件,目录的文件内容就是保存里面文件的文件名与文件的inode的映射关系),增加了文件名与新文件名的映射关系,然后让inode的引用计数++!在这里需要说一下的一个小常识就是,我们看一个目录里面有多少个子目录可以用硬链接数-2。
原理就是在我们默认创建的目录中,硬链接数就是2,一个就是目录文件名本身,另一个就是目录文件中包含的隐藏文件目录.
相关文章:

Linux中文件的理解
✨前言✨ 📘 博客主页:to Keep博客主页 🙆欢迎关注,👍点赞,📝留言评论 ⏳首发时间:2024年10月16日 📨 博主码云地址:渣渣C 📕参考书籍:…...

益安宁丸,国药准字,值得信赖
益安宁丸真品辨别唯一标准 益安宁丸是由同溢堂药业有限公司独家生产的一款中成药,主要用于调理心血管系统,广泛应用于内地市场及港澳地区。由于其疗效显著,益安宁丸在消费者中享有良好的声誉,被誉为心血管健康的守护者。然而&…...

Django项目的创建及说明(详细图解版)
Django项目的创建及说明 1、安装Django2、创建项目2.1、利用终端创建项目2.2、利用Pycharm企业版创建项目 3、默认文件介绍 1、安装Django 在终端输入下述命令行。 pip install django安装成功后执行如下命令查看Django是否安装好,若正确显示出Django版本号则安装…...

MySQL 9从入门到性能优化-二进制日志
【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…...

Cloudlog delete_oqrs_line 未授权SQL注入漏洞复现
0x01 产品简介 Cloudlog 是一个自托管的 PHP 应用程序,可让您在任何地方记录您的业余无线电联系人。使用PHP和MySQL构建的基于Web的业余无线电记录应用程序支持从HF到微波的一般站记录任务 0x02 漏洞概述 Cloudlog delete_oqrs_line 接口存在未授权SQL注入漏洞,未经身份验…...

【Linux】解锁软硬链接奥秘,高效动静态库管理的实战技巧
软硬连接和动静态库 1. 软链接1.1. 概念1.2. 特点1.3. 应用场景 2. 硬链接2.1. 概念2.2. 硬链计数2.3. 特点2.4. 应用场景 3. 动静态库3.1 库存在的原因3.2. 静态库制作与使用3.2.1 打包3.2.2. 使用 3.3. 动态库制作与使用3.3.1. 打包3.3.2. 使用 4. 解决动态库查不到的4种方法…...

【设计模式】Python 后端开发中的工厂模式设计与实现
Python 后端开发中的工厂模式设计与实现 1. 引言 在后端开发中,如何设计一套易于扩展、可维护且灵活的系统架构是开发者面临的重要课题。设计模式在这一过程中扮演了至关重要的角色,尤其是在面向对象编程中,它提供了大量解决重复问题的标准…...

划重点!入门安全测试,这几点要注意!
朋友们,今天我们一起来学习下如何做安全测试。 那么首先,什么是安全测试? 安全测试是评估和验证软件系统、应用程序或网络的安全性和强度的过程。其目标是发现和修复潜在的安全漏洞和脆弱性,以确保系统能够抵御恶意攻击和未授权…...

mysql 09 独立表空间结构
表空间中的页实在是太多了,为了更好的管理这些页面,设计 InnoDB 的大叔们提出了 区 (英文名: extent )的概念。对于16KB的页来说,连续的64个页就是一个 区 ,也就是说一个区默认占用1MB空间大小。…...

linux 虚拟环境下源码安装DeepSpeed
第一步:创建虚拟环境: conda create -n deepspeed python3.10 第二步:进入虚拟环境,安装Pytorch 2.3.1 # CUDA 12.1 conda install pytorch2.3.1 torchvision0.18.1 torchaudio2.3.1 pytorch-cuda12.1 -c pytorch -c nvidia 第…...

常见八大排序算法
今天我们带来数据结构中常见的8大排序算法。 排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性冒泡排序O(n方)O(n方)O(n方)O(1)稳定插入排序O(n方)O(n方)O(n方)O(1)稳定选择排序O(n方)O(n方)O(n方)O(1)不稳定希尔排序O(n1.3方到1,5方)O(n)O(n方)O(1)不稳定堆排序O(n lo…...

汽车免拆诊断案例 | 2022款大众捷达VS5车行驶中挡位偶尔会锁在D3挡
故障现象 一辆2022款大众捷达VS5汽车,搭载EA211发动机和手自一体变速器,累计行驶里程约为4.5万km。该车行驶中挡位偶尔会锁在D3挡,车速最高约50 km/h,且组合仪表上的发动机故障灯和EPC灯异常点亮。 故障诊断 用故障检测仪检…...

Linux之HugePage的原理与使用
Linux之HugePage的原理与使用 虚拟地址与物理地址虚拟地址物理地址虚拟地址与物理地址的转换 HugePage的概念Linux使用HugePage创建HugePage在程序中使用HugePage 总结 虚拟地址与物理地址 在研究HugePage之前,首先需要明白虚拟地址和物理地址的概念。在计算机系统…...

一步步优化Redis实现分布式锁
分布式锁概念 在多线程的程序里,为了避免同时操作一个共享变量产生数据问题,会加一个互斥锁,以确保共享变量的正确性,使用范围是同一个进程。 那如果是多个进程,需要同时操作一个共享资源,如何互斥呢&…...

C++进阶——二叉搜索树
目录 一、基本概念 二、性能分析 三、模拟实现 四、使用场景 1.key搜索场景 2.key/value搜索场景 一、基本概念 二叉搜索树(Binary Search Tree),看名字就知道,是可以用来搜索数据的一种二叉树。 它可以是空树(一个数据都…...

Require:业界优秀的HTTP管理方案。
方案异步JDK额外依赖特点HttpURLConnection 【优点】Java内置,简单易用。对于简单的HTTP请求和响应处理非常合适。 【缺点】功能相对较少,不支持现代特性(如异步请求、连接池等)。API相对繁琐,处理复杂请求时代码冗长。…...

装饰模式(Decorator Pattern)在 Go 语言中的应用
文章目录 引言什么是装饰模式?在Go语言中的应用定义接口实现具体逻辑创建装饰器使用装饰器 装饰模式 vs 中间件装饰模式中间件区别 总结 引言 在软件开发中,设计模式是解决常见问题的模板。装饰模式(Decorator Pattern)是一种结构…...

Windows系统部署redis自启动服务
文章目录 引言I redis以本地服务运行(Windows service)使用MSI安装包配置文件,配置端口和密码II redis服务以终端命令启动缺点运行redis-server并指定端口和密码III 知识扩展确认redis-server可用性Installing the Service引言 服务器是Windows系统,所以使用Windows不是re…...

34岁IT男的职场十字路口:是失业预警,还是转型契机?
在信息技术这片充满机遇与挑战的广袤领域,34岁,一个看似正值壮年却暗藏危机的年龄,成为了许多IT男性不得不面对的职场考验。当“34岁现象”逐渐凸显,我们不禁要问:在这个快速变化的时代,34岁的IT男…...

复试经验分享《三、计算机学科专业基础综合》- 数据结构篇
复试经验分享 三、计算机学科专业基础综合 3.1 数据结构 3.1.1 概念 时间复杂度 时间复杂度是指执行算法所需要的计算工作量一般情况下,按照基本操作次数最多的输入来计算时间复杂度,并且多数情况下我们去最深层循环内的语句所描述的操作作为基本操作…...

数学建模算法与应用 第16章 优化与模拟方法
目录 16.1 线性规划 Matlab代码示例:线性规划求解 16.2 整数规划 Matlab代码示例:整数规划求解 16.3 非线性规划 Matlab代码示例:非线性规划求解 16.4 蒙特卡洛模拟 Matlab代码示例:蒙特卡洛模拟计算圆周率 习题 16 总结…...

windows下安装、配置neo4j并服务化启动
第一步:下载Neo4j压缩包 官网下载地址:https://neo4j.com/download-center/ (官网下载真的非常慢,而且会自己中断,建议从以下链接下载) 百度网盘下载地址:链接:https://pan.baid…...

【JVM】—深入理解G1回收器—回收过程详解
深入理解G1回收器—回收过程详解 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 文章目录 深入理解G1回收…...

2、CSS笔记
文章目录 二、CSS基础CSS简介CSS语法规范CSS代码风格CSS选择器CSS基础选择器标签选择器类选择器--最常用id选择器通配符选择器 CSS复合选择器交集选择器--重要并集选择器--重要后代选择器--最常用子代选择器--重要兄弟选择器相邻兄弟选择器通用兄弟选择器 属性选择器伪类选择器…...

使用XML实现MyBatis的基础操作
目录 前言 1.准备工作 1.1⽂件配置 1.2添加 mapper 接⼝ 2.增删改查操作 2.1增(Insert) 2.2删(Delete) 2.3改(Update) 2.4查(Select) 前言 接下来我们会使用的数据表如下: 对应的实体类为:UserInfo 所有的准备工作都在如下文章。 MyBatis 操作…...

智汇云舟亮相WAFI世界农业科技创新大会,并参编数字农业产业图谱
10月10日,2024WAFI世界农业科技创新大会农食行业创新与投资峰会在北京金海湖国际会展中心举行。中国农业大学MBA教育中心主任、教授付文阁、平谷区委常委、统战部部长刘堃、华为公共事业军团数字政府首席专家刘丹、荷兰瓦赫宁根大学前校长Aalt Dijkhuizen、牧原食品…...

昇思MindSpore进阶教程--数据处理性能优化(中)
大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 shuffle性能优化 shuffle操作主要是对有…...

Vivado - Aurora 8B/10B IP
目录 1. 简介 2. 设计调试 2.1 Physical Layer 2.2 Link Layer 2.3 Receiver 2.4 IP 接口 2.5 调试过程 2.5.1 Block Design 2.5.2 释放 gt_reset 2.5.3 观察数据 3. 实用技巧 3.1 GT 坐标与布局 3.1.1 选择器件并进行RTL分析 3.1.2 进入平面设计 3.1.3 收发器布…...

图(Java语言实现)
一、图的概念 顶点(Vertex):图中的数据元素,我们称之为顶点,图至少有一个顶点(非空有穷集合)。 边(Edge):顶点之间的关系用边表示。 1.图(Graph…...

GPT 生成绘画_Java语言例子_超详细
基于spring ai :简化Java AI开发,提升效率与维护性 过去在使用Java编写AI应用时,主要困境在于缺乏统一的标准化封装,开发者需要针对不同的AI服务提供商查阅各自独立的文档并进行接口对接,这不仅增加了开发的工作量&am…...