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

news2025/5/25 2:33:49

在这里插入图片描述

👦个人主页: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.coloradmin.cn/o/1695429.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯发布ELLA:为扩散模型注入LLM能力,提升复杂场景的图像生成,准确率超90%

前言 近年来,基于扩散模型的文本到图像生成技术取得了显著进步,能够生成高质量、逼真的图像。然而,大多数扩散模型仍然使用CLIP作为文本编码器,这限制了它们理解复杂提示的能力,例如包含多个物体、详细属性、复杂关系…

Elasticsearch 分析器的高级用法一(同义词,高亮搜索)

Elasticsearch 分析器的高级用法一(同义词,高亮搜索) 同义词简介分析使用同义词案例 高亮搜索高亮搜索策略unifiedplainvh 同义词 简介 在搜索场景中,同义词用来处理不同的查询词,有可能是想表达相同的搜索目标。 例…

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一: 环境变量配置 首先,你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python,而IDLE使用的是另一个路径下的Python,那么你在cmd中下载的库,IDL…

编程实现标题栏窗口摇动——显示桌面的未公开细节研究

目录 前言 一、“窗口摇动”功能内部原理 二、explorer.exe 中的 “窗口抖动” 实现 三、“切换到桌面” 功能所扩展的内部细节 四、概念验证 五、进一步研究如何自定义保留窗口列表 原文出处链接:[https://blog.csdn.net/qq_59075481/article/details/139204…

内网穿透--Spp-特殊协议-上线

免责声明:本文仅做技术交流与学习... 目录 spp项目: 一图通解: 1-下载spp 2-服务端执行命令 3-客户端执行命令 4-服务端cs监听&生马 spp项目: GitHub - esrrhs/spp: A simple and powerful proxy 支持的协议:tcp、udp、udp、icmp、http、kcp、quic 支持的…

Gb 2024-05-22开源项目日报Top10

根据Github Trendings的统计,今日(2024-05-22统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3非开发语言项目2Jupyter Notebook项目2Rust项目2JavaScript项目1Lua项目1编程面试大学:成为软件工程师的全面学习计划 创建周期:2…

在ubuntu22.04里网站源码连不上mysql数据库

在ubuntu22.04里网站源码连不上mysql数据库。后来找到了原因。 连不上的时候有报错信息: ERROR 1698 (28000): Access denied for user rootlocalhost 用在网上搜索该报错信息,找到了两篇有用的文章,用这两篇文章里的处理方法解决了问题。 …

三个有意思的链表面试题的完成

上一篇博客我们已经完成了链表的所有内容,那么这一篇博客我们来看一下三个特别有意思的链表题目。 **第一个题目如下:**相信不少朋友看到这题目就已经晕了,那就简单说明下这个题目,题目就是创建一个链表,其中每个节点…

比勤奋更重要的是系统思考的能力

不要在接近你问题症状的地方寻找解决办法,要追溯过去,查找问题的根源。通常,最有效的活动是最微妙的。有时最好按兵不动,使系统自我修正,或让系统引导行动。有时会发现,最好的解决办法出现在完全出乎预料的…

Redis 实战 - 缓存异常及解决方案

文章目录 概述一、缓存穿透1.1 缓存穿透是什么1.2 解决方案 二、缓存击穿2.1 缓存击穿是什么2.2 解决方案 三、缓存雪崩3.1 缓存雪崩是什么3.2 解决方案 四、拓展4.1 缓存预热4.2 缓存降级 五、结语 把今天最好的表现当作明天最新的起点…….~ 概述 在实…

【漫画算法】哈希表:古代皇帝的秘密魔法书

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…

如何确保大模型 RAG 生成的信息是基于可靠的数据源?

在不断发展的人工智能 (AI) 领域中,检索增强生成 (RAG) 已成为一种强大的技术。 RAG 弥合了大型语言模型 (LLM) 与外部知识源之间的差距,使 AI 系统能够提供更全面和信息丰富的响应。然而,一个关键因素有时会缺失——透明性。 我们如何能够…

Android窗口管理

一 概述 本篇文章主要讲 Window、WindowManager、WindowManagerService 三者之间的关系及其运行机制。总的来说 Window 表示的是一种抽象的功能集合,具体实现为 PhoneWindow。WindowManager 是外界访问 Window 的入口,对 Window 的访问必须通过 Window…

状态转换图

根据本章开头讲的结构化分析的第3条准则,在需求分析过程中应该建立起软件系统的行为模型。状态转换图(简称为状态图)通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为。此外,状态图还指明了作为特定事件的结果系统将做哪些动作(例如,处理数据)。因此,状态图提供了…

【轻松压缩,一键搞定】您的图片处理神器来了!

压图地址 一个功能强大的图片处理工具,它可以满足用户对于图片压缩、格式转换、质量调节以及长图片分割等多种需求。 【轻松压缩,一键搞定】您的图片处理神器来了! 🎉 您是否曾为图片太大无法上传而烦恼?是否为图片格…

rk3568_atomic

文章目录 前言一、atomic是什么?二、原子操作API函数1.atomic原子操作2.原子位操作API三、atomic驱动实验总结前言 本文记录的是正点原子rk3568开发板的atomic实验 一、atomic是什么? 不同的线程在进行读写的过程中,可能会冲突乱入,导致会有预想不到的结果。所以为了让数…

信息系统项目管理师0131:输出(8项目整合管理—8.7监控项目工作—8.7.3输出)

点击查看专栏目录 文章目录 8.7.3 输出8.7.3 输出 工作绩效报告工作绩效信息可以用实体或电子形式加以合并、记录和分发。基于工作绩效信息,以实体或电子形式编制形成工作绩效报告,以制定决策、采取行动或引起关注。根据项目沟通管理计划,通过沟通过程向项目干系人发送工作绩…

文档档案管理系统整体建设方案书(实际项目原件word2024)

1.系统概述 1.1.需求描述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 数据备份技术 3.系统功能设计 3.1.功能清单列表 3.2.基础数据管理 3.3.位置管理 3.4.文档使用 3.5.文档管理 软件全套资料包获取方式①:软件项…

[windows系统安装/重装系统][step-4][番外篇-2]N卡驱动重装 |解决:开机几小时后电脑卡顿 | 后台自动运行了上千个Rundll32进程问题

现象 开机几小时后,电脑变卡,打开后台管理器都卡,后台管理去转圈圈一小会儿后看到后台进程上千个,好多个Rundll32进程 重启下运行会稍快 重启后运行快,后台管理器反应也快 打开后台管理器不卡(几小时后打…

Hadoop3:HDFS中DataNode与NameNode的工作流程

一、DataNode中的数据情况 数据位置 /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-823420375-192.168.31.102-1714395693863/current/finalized/subdir0/subdir0块信息 每个块信息,由两个文件保存,xxx.meta保存的是数据长度、校验和、时间戳&am…