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

Linux:文件流指针 与 文件描述符

目录

  • 一、文件描述符
  • 二、文件流指针
  • 三、缓冲区

  之前讲解过了IO库函数和IO接口,库函数是对系统调用接口的封装,也就是说实际上在库函数内部是通过调用系统调用接口来完成最终功能的。

  库函数通过文件流指针操作文件,系统调用接口通过文件描述符操作文件。实际上文件流指针就是系统将文件描述符封装后得来的,本文来简单聊一聊它们。

一、文件描述符

文件描述符:

  使用系统调用接口open打开一个文件,如果打开成功会返回一个非负整数,这个数字就是这个文件的文件描述符,就是一个文件的操作句柄。

操作句柄:

  用杯子来举例,我们要喝水时,端着杯子的把手,借助这个把手来操作杯子,这个把手就是杯子的操作句柄。在文件操作中,我们通过文件描述符来操作对应的文件,这个文件描述符就是文件的操作句柄。

为什么可以通过文件描述符操作文件?

  文件是什么?文件就是一块磁盘空间。给文件写入数据,其实就是写入到了磁盘的指定位置。但磁盘中不止存储了这个文件,还有一块空间用来存储这个文件的描述信息,这个描述信息就是文件的属性。这就类似于进程pcb,pcb就是对动态运行的程序的描述。

  如图:硬盘中存储了文件和文件的描述信息。

文件信息

  在程序的运行中,我们可能会有多个文件被使用,所以我们要把这些文件管理起来,让我们可以高效的访问。

  因此在Linux的进程pcb中还有一个用来存储文件相关内容的结构体 files_struct,这个结构体中有一个指针数组 fd_arr[],这个数组中存储的就是每个文件的描述信息 struct_file 的地址,而这个地址的下标就是文件描述符

  通过文件描述符控制文件其实就是找到files_struct后,找到fd_arr数组,然后根据的文件描述符(也就是数组下标),找到数组中的对应的地址,然后就可以找到文件的描述信息。

总体信息

二、文件流指针

  系统调用接口通过文件描述符来操作文件,而库函数则是通过文件流指针来操作对应文件。

库函数和系统调用接口的关系

  库函数其实是对系统调用接口的封装,系统调用接口加上一点其他内容就构成了库函数。因此文件流指针其实就是对文件描述符的封装,它的内部也是使用文件描述符来操作文件的。

  文件流指针就是一个 struct FILE* 类型的变量,而struct FILE是stdio.h头文件中的结构体,我们来看一下头文件中对于FILE的描述。

  如图:头文件中可以看到,FILE其实是_IO_FILE的别名,所以FILE其实就是_IO_FILE,FILE* 指针就是 _IO_FILE* 指针。

重命名

  接下来看一下 _IO_FILE 结构体的部分内容:269行的 int _fileno 就是文件描述符,结构体把文件描述符封装了起来。

_IO_FILE

三、缓冲区

  IO库函数有缓冲区,而系统调用IO接口没有缓冲区,因为缓冲区封装在库函数中的 _IO_FILE 结构体中。

缓冲区
  这幅图的252到263行其实就是缓冲区,用读缓冲区举个例子。缓冲区是在用户空间中申请的一块空间,252行的指针指向这块空间的当前读写位置,253行的指针指向这块缓冲区空间的结束地址,254行的指针指向这块空间的开始地址。

  当读取数据时,就会从当前读写位置开始,一直读取到空间结束。写入文件时,从当前读写位置开始写,当写入到结束位置,代表着缓冲区写满了,需要刷新了。这样就用指针实现了缓冲区。

http://www.lryc.cn/news/37917.html

相关文章:

  • 基于FPGA实现正弦插值算法
  • JavaWeb_会话技术
  • Reactor响应式流的核心机制——背压机制
  • [数据结构]栈的深入学习-java实现
  • 网络编程基础
  • 华为OD机试题 - 数列还原(JavaScript)| 机考必刷
  • 10-Oracle存储过程(创建,修改,使用及管理)
  • 创建线程的三种方法
  • 第一章---Pytorch快速入门---第三节---pytorch中的数据操作和预处理
  • 【代码随想录训练营】【Day38】第九章|动态规划|理论基础|509. 斐波那契数|70. 爬楼梯|746. 使用最小花费爬楼梯
  • 华为OD机试题 - 快递货车(JavaScript)| 机考必刷
  • 前端——7.图像标签和路径
  • java -- stream流
  • 【Spring6】| Bean的四种获取方式(实例化)
  • 01: 新手学SpringCloud前需知道的5点
  • ubuntu apt安装arm交叉编译工具
  • 阿里云一面经历
  • Java Stream中 用List集合统计 求和 最大值 最小值 平均值
  • 【Linux】多线程---线程控制
  • 秒杀高并发解决方案
  • 【每日一题】蓝桥杯加练 | Day07
  • 条件语句(分支语句)——“Python”
  • 论文投稿指南——中文核心期刊推荐(国家财政)
  • 面向数据安全共享的联邦学习研究综述
  • Redis经典五种数据类型底层实现原理解析
  • Jackson 返回前端的 Response结果字段大小问题
  • 每天五分钟机器学习:你理解贝叶斯公式吗?
  • C++的入门
  • 数据的存储
  • Linux查看UTC时间