当前位置: 首页 > news >正文

Linux 基础IO

一. 系统调用接口

在这里插入图片描述

  • fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
  • open close read write lseek 都属于系统提供的接口,称之为系统调用接口

根据这张图, 系统调用接口和库函数的关系, 一目了然。

二. 文件描述符

  • 文件描述符fd就是一个整数。
  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器。

在这里插入图片描述

文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files,
指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针。所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。

三. Linux中的IO接口

3.1 open函数

int open(const char *pathname, int flags);
  • 功能:打开或创建文件。

  • 参数:
    pathname:要打开或创建的文件名。
    flags:指定文件如何被打开(读取、写入、追加等),可以使用OR运算符组合多个标志。

  • 返回值:成功时返回非负整数作为文件描述符,失败则返回-1,并设置errno。

3.2 close函数

int close(int fd);
  • 功能:关闭一个打开的文件描述符。
  • 参数:
    fd:要关闭的文件描述符。
  • 返回值:成功时返回0,失败则返回-1,并设置errno。

3.3 read函数

ssize_t read(int fd, void *buf, size_t count);
  • 功能:从文件描述符读取数据。
  • 参数:
    fd:要读取的文件描述符。
    buf:指向存储读取数据的缓冲区的指针。
    count:尝试读取的最大字节数。
  • 返回值:成功时返回实际读取的字节数,如果达到文件末尾则返回0。失败则返回-1,并设置errno。

3.4 write函数

ssize_t write(int fd, const void *buf, size_t count);
  • 功能:向文件描述符写入数据。
  • 参数:
    fd:要写入的文件描述符。
    buf:指向要写入的数据的指针。
    count:要写入的字节数。
  • 返回值:成功时返回实际写入的字节数,可能小于count(例如,当写入非阻塞文件描述符时)。如果返回值为0,表示没有数据被写入。失败则返回-1,并设置errno。

3.5 dup2函数

int dup2(int oldfd, int newfd);
  • 功能:复制一个文件描述符,使其具有新的文件描述符号。
  • 参数:
    oldfd:现有的文件描述符。
    newfd:新文件描述符的号码。如果newfd已经打开,它将被关闭,然后设置为oldfd的副本。
  • 返回值:成功时返回新的文件描述符,通常是newfd。失败则返回-1,并设置errno。

3.6 lseek函数

off_t lseek(int fd, off_t offset, int whence);
  • 功能:改变文件描述符的读/写位置。
  • 参数:
    fd:要改变位置的文件描述符。
    offset:相对于whence的位置偏移量。
    whence:定义了offset的参考点,可以是SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件结尾)。
  • 返回值:成功时返回新的文件偏移量,失败则返回-1,并设置errno。

四. Linux文件系统

4.1 ex2文件系统

磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。启动块(Boot Block)的大小是确定的。以下该图为磁盘文件系统图:
在这里插入图片描述

  1. 超级块(Superblock):
    超级块位于文件系统的开头,通常在第一个块组中,但为了容错,每个块组都会复制一份超级块它包含了整个文件系统的关键信息,如文件系统的大小、状态、空闲块的数量等。如果某个超级块损坏了,可以使用其他块组中的备份超级块来恢复文件系统。
  2. 组描述符表(Group Descriptor Table):
    每个块组都有一个组描述符,这个表记录了所有块组的信息。组描述符中包含了指向该组内位图和inode表的指针,以及关于该组的一些统计信息,比如有多少个空闲块或inode。
  3. 块位图(Block Bitmap):
    块位图用于追踪块组内的哪些块已经被分配出去,哪些块还处于未分配状态。每一位对应一个块,如果位为1,则表示对应的块已被分配;如果位为0,则表示该块尚未被分配。
  4. inode位图(Inode Bitmap):
    inode位图与块位图类似,但它用于追踪inode的状态。每一位代表一个inode,位为1表示inode已分配,位为0表示inode未分配。
  5. inode表(Inode Table):
    每个块组都有一个inode表,用于存储该组内的所有inode。inode是文件系统中用来存储文件元数据(例如文件类型、权限、时间戳等)的数据结构。每个文件或目录在文件系统中都有一个唯一的inode号。
  6. 数据块(Data Blocks):
    数据块是用来存储文件实际内容的空间。文件系统中的每个文件都可以占用一个或多个数据块。数据块的分配是通过inode中的指针来实现的,这些指针指向实际存储文件数据的数据块。

4.2 inode索引节点

每个文件在文件系统中都有一个唯一的inode编号,inode包含了文件的各种属性和信息,但不包括文件名和文件的实际数据。

inode的主要内容:
文件类型:指示文件是普通文件、目录、符号链接还是其他类型的特殊文件(如设备文件)。
文件权限:定义了文件的所有者、所属组和其他用户的读、写、执行权限。
文件所有权:包括文件的所有者(用户ID)和所属组(组ID)。
文件大小:以字节为单位的文件大小。
时间戳:包括文件的最后修改时间(mtime)、最后访问时间(atime)和inode最后更改时间(ctime)。
链接数:指向该inode的硬链接数量。
指向数据块的指针:这些指针指向存储文件实际内容的数据块。对于大文件,inode可能包含直接指针、间接指针、双重间接指针甚至三重间接指针。
特殊标志:例如,是否设置了追加只写标志(append-only)、不可删除标志(immutable)等。

4.3 文件是如何创建的

  1. 存储属性
    内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中。
  2. 存储数据
    该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推。
  3. 记录分配情况
    文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。
  4. 添加文件名到目录
    新的文件名abc。linux如何在当前的目录中记录这个文件?内核将入口(263466,abc)添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。

4.4 硬链接和软链接

4.4.1 硬链接
  • 创建方法:
    ln source target
    
  • 定义: 硬链接是指向同一个inode的不同文件名。也就是说,多个文件名可以指向同一个文件数据。
  • 特点
    1. 共享inode:硬链接文件和原始文件共享同一个inode,因此它们实际上是同一个文件的不同名字。
    2. 数据一致性:对任何一个硬链接文件进行修改,都会影响到其他所有硬链接文件,因为它们共享相同的数据块。
      删除影响:删除一个硬链接文件不会删除实际的数据,只有当最后一个硬链接被删除后,inode才会被释放,数据块也会被回收。
    3. 限制:硬链接不能跨文件系统创建,只能在同一文件系统内部创建。
4.4.2 软链接
  • 创建方法:

    ln -s target symbolic_link
    
  • 定义: 软链接(符号链接)是一个特殊的文件,它包含了指向另一个文件或目录的路径名。它就像Windows中的快捷方式。

  • 特点

    1. 独立inode:软链接有自己的inode,它存储的是目标文件的路径名。
    2. 路径依赖:软链接依赖于目标文件的路径,如果目标文件被移动或删除,软链接会失效(变成“断链”)。
    3. 跨文件系统:软链接可以跨文件系统创建。
    4. 支持目录:软链接可以指向文件或目录。
    5. 灵活性:软链接可以创建更复杂的文件系统结构,例如跨目录的快捷方式。

————————————————————
感谢大家观看,不妨点赞支持一下吧喵~
如有错误,随时纠正喵~


http://www.mrgr.cn/news/63823.html

相关文章:

  • 【OpenGL】知识点
  • 2024-10月的“冷饭热炒“--解读GUI Agent 之computer use?phone use?——多模态大语言模型的应用进阶之路
  • 手敲Webpack 5:React + TypeScript项目脚手架搭建实践
  • Vue v-on
  • DBeaver如何删除一行或多行数据
  • 便携剃须刀性能王者,小但专业,未野MAX SE剃须刀测评
  • Lucene的使用方法与Luke工具(2)
  • 【NOIP普及组】 FBI树
  • ATom:加州理工学院(CIT)化学电离质谱仪(CIMS)测量的气相有机和无机分析物的浓度CIT-CIMS
  • 代码随想录算法训练营第十七天| 654最大二叉树、617合并二叉树、700二叉搜索树中的搜索、98验证二叉搜索树
  • mlp文件夹继续阅读
  • ST IoT Wireless 物联网与无线技术 研讨会
  • 现代生产系统DORA的应用与集成
  • 理解typeScript中的高级类型
  • 如何在Linux下部署自己的ZFile开源网盘
  • 使用MongoDB Atlas构建无服务器数据库
  • CentOS下载ISO镜像的方法
  • CF983(div2)(未补)
  • Ubuntu软件包管理机制
  • PyTorch实践-CNN-鸢尾花分类
  • 资深项目经理推荐的这五款国产项目管理软件值得收藏使用
  • Kotlin一之内置类型
  • 【数据结构】构造函数和析构函数
  • Linux 进程间通信——管道
  • 问答系统评估标准
  • 安装scrcpy-client模块av模块异常,环境问题解决方案