【Linux】简单模拟C语言文件标准库FILE

在这里插入图片描述

👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍


目录

  • 前言
  • 一、FILE结构体设计
  • 二、fopen函数
  • 二、fwrite函数
  • 三、fflush函数
  • 四、fclose函数
  • 五、总结及相关代码

前言

在这里插入图片描述

在C语言中,FILE结构体一定封装了诸如文件描述符等字段,使得C语言文件操作的库函数可以很好的调用系统调用,因此程序员可以更加方便地使用高级接口来完成任务,而无需深入了解底层系统调用的实现细节。

这篇博客将带领大家深刻理解C语言文件操作函数底层是如何封装系统调用接口,以及C语言用户级缓冲区的现象。

注:本篇博客不是为了造一个更好的轮子,而是重在理解!!!

一、FILE结构体设计

在这里插入图片描述

(以上是库封装的FILE相关字段)

我们知道,C语言的文件操作函数底层必定会调用系统调用接口,而在往期博客中我们知道,文件相关的系统调用接口都是由文件描述符来定位文件的,因此,FILE结构体必定封装了文件描述符。

而我们这篇博客还要实现缓冲区现象,因此,FILE结构体还会封装维护缓冲区的相关字段。

在这里插入图片描述

  • _fileno:文件描述符。
  • outbuffer:输出缓冲区。需要注意的是,用户级缓冲区通常是通过动态内存分配函数(如mallocnew)在堆区分配的,大小是不固定的。
  • out_pos:当前缓冲区字符的个数。

二、fopen函数

C语言中文件打开操作fopen底层调用了系统调用接口open

在这里插入图片描述

open函数的更多详细用法请查看此篇博客:点击跳转

// fopen函数模型
FILE *fopen(const char *path, const char *mode);
// path: 文件的路径
// mode: 文件的打开方式

文件打开的方式mode有很多种,大家可以通过man手册查询,这里我重点实现以下常见的三种:

  • "w": 以只写的方式打开方式。文件不存在会自动创建,并且每打开一次都会将文件内容清空再写入。

  • "a": 以追加的方式打开文件。文件不存在会自动创建,不会对文件原有的内容做清空,而是追加写入。

  • "r": 以只读的方式打开文件,文件不存在会报错。

此外,当使用fopen函数打开文件,对于普通文件,默认情况下会使用全缓冲来刷新缓冲区,即直到缓冲区满了或者遇到'\n'才将缓冲区中的内容写入磁盘。

在这里插入图片描述

二、fwrite函数

C语言中文件写入操作fwrite底层也调用了系统调用接口write

在这里插入图片描述

write函数的更多详细用法请查看此篇博客:点击跳转

// fwrite函数模型
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • ptr:指向要写入的数据块的指针。通常使用void*类型的指针,可以传递任何类型的数据块。需要注意的是,ptr指向的数据必须与sizenmemb参数相对应,即size * nmemb表示要写入的总字节数。

  • size:要写入每个数据块的字节数。

  • nmemb:要写入的数据块的数量。表示要写入多少个数据块。

  • stream:指向要写入的文件的指针。需要使用标准库函数fopen()成功打开文件后,将返回的文件指针作为参数传递给fwrite()函数。

  • nmemb值充当返回值。

在这里插入图片描述

用户调用fwrite时,并不会直接将内容直接写入文件中,而是将数据写入到用户级缓冲区,然后通过一定条件,再将缓冲区的内容写入到文件中。详细步骤如下:

  1. 判断当前用户级缓冲区是否被填满。如果满了,先对缓冲区刷新,再进行后续操作。
  2. 如果遇到'\n',就将'\n'之间的字符全部刷新。
  3. 若不满足条件继续将字符往缓冲区里塞。

在这里插入图片描述

三、fflush函数

当用户调用fflush函数时,不管缓冲区是否满了还是什么,直接刷新。因此,fflush函数一定封装了系统调用接口write

// fflush函数原型
int fflush(FILE *stream);

在这里插入图片描述

四、fclose函数

fclose()函数是C语言标准库中用于关闭文件流的函数。它的作用是将缓冲区中剩余的数据写入到文件中,并释放系统资源。因此它的底层必定会调用fflush函数以及系统调用close()

int close(int fd);

在这里插入图片描述

五、总结及相关代码

  • 数据到达文件一共要执行3次拷贝,第一次是拷贝到用户级缓冲区、第二次是拷贝到系统级缓冲区、最后一次则是真正写入文件中(第二次到第三次是由操作系统帮我们完成的)。

  • 在模拟实现fwrite时,我们将一个字符一个字符拷贝到缓冲区,不满足条件,如缓冲区没有满或者没有遇到'\n'就继续拷贝至缓冲区,这不是变相减少了调用系统调用的次数,从而提高IO效率!

本篇博客相关代码:点击跳转

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows 安装 使用 nginx

windows 安装 使用 nginx nginx官网下载地址:https://nginx.org/en/download.html 下载稳定版本即可 下载压缩包解压到即可 进入文件夹中,打开命令行窗口,执行启动命令 start nginx.exe验证(默认是80端口)&#x…

OrangePi AIpro 快速上手初体验——接口、样例和目标检测

​ 一、 开发板简介 OrangePi AIpro开发板是香橙派联合华为精心打造的高性能 AI 开发板,其搭载了昇腾 AI 处理器,可提供 8TOPS INT8 的计算能力,内存提供了 8GB 和 16GB两种版本。可以实现图像、视频等多种数据分析与推理计算,可…

猫狗分类识别模型建立②模型建立

一、导入依赖库 pip install opencv-python pip install numpy pip install tensorflow pip install keras 二、模型建立 pip install opencv-python pip install numpy pip install tensorflow pip install kerasimport os import xml.etree.ElementTree as ETimpor…

[双指针] --- 快乐数 盛最多水的容器

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 算法Journey 本篇博客我们分享一下双指针算法中的快慢指针以及对撞双指针,下面我们开始今天的学习吧~ 🏠 快乐数 📒 题…

LabVIEW中实现Trio控制器的以太网通讯

在LabVIEW中实现与Trio控制器的以太网通讯,可以通过使用TCP/IP协议来完成。这种方法包括配置Trio控制器的网络设置、使用LabVIEW中的TCP/IP函数库进行数据传输和接收,以及处理通讯中的错误和数据解析。本文将详细说明实现步骤,包括配置、编程…

分享10个我常逛的技术社区

多逛社区,了解新鲜的事情和技术,或许会有意想不到的观点给你灵感! 国外技术交流网站合集(30个类别)的github地址: https://github.com/sdmg15/Best-websites-a-programmer-should-visit 这里收集了超过200个程序员应该…

K8s 小白入门|从电影配乐谈起,聊聊容器编排和 K8s

来听听音乐 电影,是我们生活中的重要调味剂。 配乐,是电影中不可或缺的一部分。 有的时候,配乐可以跟剧情共振,让你按捺不住自己的情绪,或眼含热泪、或慷慨激昂、或人仰马翻、或怅然若失; 有的时候&…

美团拼好饭小程序mtgsig1.2分析(补环境分析)

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!wx a15018601872 本文章未…

【AI绘画Stable Diffusion】单人LoRA模型训练,打造你的专属模型,新手入门宝典请收藏!

大家好,我是灵魂画师向阳 本期我将教大家如何进行LoRA模型训练,打造你的专属模型,内容比较干,还请耐心看完! 随着AIGC的发展,许多传统工作岗位正逐渐被AI取代。同时,AI变革也在创造前所未有的…

【C++】---二叉搜索树

【C】---二叉搜索树 一、二叉搜索树概念二、二叉搜索树操作(非递归)1.二叉搜索树的查找 (非递归)(1)查找(2)中序遍历 2.二叉搜索树的插入(非递归)3.二叉搜索树…

三十三、openlayers官网示例Drawing Features Style——在地图上绘制图形,并修改绘制过程中的颜色

这篇讲的是使用Draw绘制图形时根据绘制形状设置不同颜色。 根据下拉框中的值在styles对象中取对应的颜色对象,new Draw的时候将其设置为style参数。 const styles {Point: {"circle-radius": 5,"circle-fill-color": "red",},LineS…

P2341 受欢迎的牛

题目描述 每一头牛的愿望就是变成一头最受欢迎的牛。现在有 N 头牛,给你 M 对整数,表示牛 A 认为牛 B 受欢迎。这种关系是具有传递性的,如果 A 认为 B 受欢迎,B 认为 C 受欢迎,那么牛 A 也认为牛 C 受欢迎。你的任务是…

UVa11604 General Sultan

UVa11604 General Sultan 题目链接题意分析AC 代码 题目链接 UVA - 11604 General Sultan 题意 给出一些0和1组成的模式串,问是否存在一个串使得有多种方案将这个串分解成模式串。    给一个包含n(n≤100)个符号的二进制编码方式&#xff…

基础—SQL—DQL(数据查询语言)基础查询

一、引言 1、介绍: 分类全称描述DQL英文全称:Data Query Language(数据查询语言)主要是学习对数据库表中的记录进行查询的语句 2、讲解 日常的开发中或者对于一个正常的业务系统中,对于查询的操作次数是远远多于数据的增删改的频次。例如…

Ansible自动化运维中的Setup收集模块应用详解

作者主页:点击! Ansible专栏:点击! 创作时间:2024年5月22日13点14分 💯趣站推荐💯 前些天发现了一个巨牛的🤖人工智能学习网站,通俗易懂,风趣幽默&#xf…

ABB 控制柜

1,主计算机:相当于电脑的主机,用于存放系统和数据,需要24V直流电才能工作。执行用户编写的程序,控制机器人进行响应的动作。主计算机有很多接口,比如与编程PC连接的服务网口、用于连接示教器的网口、连接轴…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域,同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论,它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例,将这些抽象…

深入解析Web前端三大主流框架:Angular、React和Vue

Web前端三大主流框架分别是Angular、React和Vue。下面我将为您详细介绍这三大框架的特点和使用指南。 Angular 核心概念: 组件(Components): 组件是Angular应用的构建块,每个组件由一个带有装饰器的类、一个HTML模板、一个CSS样式表组成。组件通过输入(@Input)和输出(…

【Python】解决Python报错:TypeError: %d format: a number is required, not str

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

.NET 直连SAP HANA数据库

前言 上个项目碰到的需求,IT部门要求直连SAP的HANA数据库,以只读的权限读取SAP部门开发的CDS视图,是个有点复杂的工程,需要从成品一直往前追溯到原材料的产地,和交货单、工单、采购订单有相当程度上的关联 IT部门要求…