深入理解C语言对文件的包装与缓冲区

您所在的位置:网站首页 c语言之文件操作 深入理解C语言对文件的包装与缓冲区

深入理解C语言对文件的包装与缓冲区

2024-07-12 11:51:05| 来源: 网络整理| 查看: 265

内存级文件操作的运用 1.模拟实现文件分装2. 深入理解缓冲区的概念

1.模拟实现文件分装

【目标】 以最简单的方式,理解FILE结构体的原理。

头文件:mystdio.h(定义了MY_FILE结构体,声明fopen,fwrite,fclose,fflush函数)

#pragma once #include #define NUM 1024 #define BUFFER_NONE 1 #define BUFFER_LINE 2 #define BUFFER_ALL 4 typedef struct MY_FILE { int fd; int flags;//flush method char outputbuffer[NUM]; int current; }MY_FILE; MY_FILE* my_fpen(const char *path, const char *mode); size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, MY_FILE *stream); int my_fclose(MY_FILE *fp); int my_fflush(MY_FILE *fp);

mystdio.c文件:相关函数的实现

#include"mystdio.h" #include #include #include #include #include #include #include //fopen("a/b/c","a") //fopen("a/b/c","r") //fopen("a/b/c","w") MY_FILE* my_fpen(const char *path, const char *mode) { //1.识别标志位,确定打开方式 int flag=0; if(strcmp(mode,"r")==0)flag|=O_RDONLY; else if(strcmp(mode,"w")==0)flag|=(O_CREAT|O_WRONLY|O_TRUNC); else if(strcmp(mode,"a")==0)flag|=(O_CREAT|O_WRONLY|O_APPEND ); else {//other open method ; } //2.尝试打开文件 mode_t m=0666; int fd=0; if(flag&O_CREAT)fd=open(path,flag,m); else fd=open(path,flag); if(fd assert(ptr&&stream); //1.缓冲区如果已经满了,直接写入 if(stream->current==NUM)my_fflush(stream); //2.根据缓冲区剩余情况,进行数据拷贝 size_t user_size=size*nmemb; size_t my_size = NUM -stream->current; size_t writen=0; if(my_size>user_size) { memcpy(stream->outputbuffer+stream->current,ptr,user_size); //3.更新计数器字段 stream->current+=user_size; writen=user_size; } else { memcpy(stream->outputbuffer+stream->current,ptr,my_size); //3.更新计数器字段 stream->current+=my_size; writen=my_size; } //4.开始计划刷新数据,看看他们高效体现在哪里? //不发生刷新的本质,不进行写入,就是不进行IO,不进行调用系统调用,所以my_fwrite函数调用会非常快,数据会暂时保存在缓冲区中 //可以在缓冲区中挤压多分数据,统一进行刷新写入,本质:就是一次IO可以IO更多的数据,提高IO效率 if(stream->flags&BUFFER_ALL) { if(stream->current==NUM)my_fflush(stream); } else if(stream->flags&BUFFER_LINE) { if(stream->outputbuffer[stream->current-1]=='\n')my_fflush(stream); } else { //TODO } return writen/nmemb; } int my_fclose(MY_FILE *fp) { assert(fp); //1.冲刷缓冲区 if(fp->current>0)my_fflush(fp); //2.关闭文件 close(fp->fd); //3.释放栈空间 free(fp); return 0; } int my_fflush(MY_FILE* fp) { assert(fp); //将用户缓冲区中的数据,通过系统接口,冲刷给OS write(fp->fd,fp->outputbuffer,fp->current); fp->current=0; fsync(fp->fd); return 0; }

main函数

#include"mystdio.h" #include #include #define MYFILE "log.txt" int main() { MY_FILE *fp=my_fpen(MYFILE,"w"); if(fp==NULL) { printf("打开文件失败!\n"); return 1; } //文件操作 const char *str="hello my fwrite"; int cnt=5; while(cnt) { char buff[1024]=""; snprintf(buff,sizeof(buff),"%s:%d\n",str,cnt--); size_t size=my_fwrite(buff,strlen(buff),1,fp); sleep(1); printf("当前成功写入%lu个字符!\n",size); } my_fclose(fp); return 0; } 2. 深入理解缓冲区的概念

因为冯诺依曼体系的原因,多次的IO访问外设,速度会很慢。通过缓冲区,可以临时存储数据,再根据缓冲区刷新策略,进行一次IO将数据写入到外设中。IO次数减少,速度明显提高。

缓冲区分成有两种:用户级缓冲区+内核级缓冲区。

用户级别的缓冲区是语言提供的,按照刷新策略调用系统接口,将数据写入到内核级别的缓冲区中;内核级别的缓冲区是不可见的,也有自己的刷新策略,由OS来控制。刷新内核级别的缓冲区才是将数据存储到磁盘上面。 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭