大连市平台网站,企业融资需求怎么写,济南网站建设哪家便宜,新手怎么做自媒体✨前言✨ #x1f4d8; 博客主页#xff1a;to Keep博客主页 #x1f646;欢迎关注#xff0c;#x1f44d;点赞#xff0c;#x1f4dd;留言评论 ⏳首发时间#xff1a;2024年10月16日 #x1f4e8; 博主码云地址#xff1a;渣渣C #x1f4d5;参考书籍#xff1a…✨前言✨ 博客主页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语言会默认的打开三个文件那就是标准输入标准输出标准错误对应的文件描述符默认值分别就是012
6 dup2函数重定向
简单了解了文件描述符的原理并且知道了在C语言中会默认打开三个文件这样我们就可以知道输出重定向追加重定向的原理了就是利用上层C语言在标准输入标准输出标准错误三个文件结构体中给文件描述符默认值就是012。那么我们利用系统调用函数底层可以直接改变文件描述符的函数就可以关闭标准输出这个文件然后最新打开的文件加载到内存中的文件就会被文件描述符表中的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一个就是目录文件名本身另一个就是目录文件中包含的隐藏文件目录.