文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Linux】文件缓冲区

2023-09-06 12:49

关注

目录

提到文件缓冲区这个概念我们好像并不陌生,但是我们对于这个概念好像又是模糊的存在脑海中,之间我们在介绍c语言文件操作已经简单的提过这个概念,今天我们不妨深入理解什么是文件缓冲区

一、缓冲区图解

在这里插入图片描述

二、自定义实现文件操作函数

通过自己实现库中的一些文件操作函数更加深入的理解文件缓冲区
自定义实现的myopen和库里面的open功能大致相同。mywrite和write大致相同。myclose和close大致相同,
通过自定义实现这些系统接口,可以更加深入的了解文件在进行读写的时候系统做了哪些事情。

mystdio.h

  1 #pragma once  2   3 #include<stdio.h>  4   5 #define NUM 1024  6 #define BUFF_NONE 0x1  7 #define BUFF_LINE 0x2  8 #define BUFF_ALL  0x4  9  10 typedef struct MY_FILE 11 { 12     int fd; 13     int flags;  //flush method 刷新方式 14     char outputbuffer[NUM]; //缓冲区 15     int current; 16  17 }MY_FILE; 18  19 MY_FILE* my_fopen(const char* path,const char* mode); 20  21 size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* stream); 22  23 int my_fflush(MY_FILE* fp);                    24  25 int my_fclose(MY_FILE*fp);

mystdio.c

  1 #include "mystdio.h"  2 #include<string.h>  3 #include<sys/types.h>  4 #include<sys/stat.h>  5 #include<fcntl.h>  6 #include<unistd.h>  7 #include<malloc.h>  8 #include<assert.h>  9  10 //fopen("xxx","a"); 11 MY_FILE* my_fopen(const char* path,const char* mode) 12 { 13     //1.识别标志位 14     int flag=0; 15     if(strcmp(mode,"r")==0)flag|=O_RDONLY; 16     else if(strcmp(mode,"w")==0)flag|=(O_CREAT | O_WRONLY | O_TRUNC); 17     else if(strcmp(mode,"a")==0)flag|=(O_CREAT | O_WRONLY | O_APPEND); 18     else{ 19         //other operator  "r+" ,"w+" "a+" 20     } 21     //2.尝试打开文件 22     mode_t m=0666; //文件权限 23     int fd=0; 24     if(flag & O_CREAT)fd=open(path,flag,m); 25     else fd=open(path,flag); 26                    27     if(fd<0)return NULL; //打开文件失败 28  29     //3.给用户返回MY_FILE对象,需要构建 30     MY_FILE* mf= (MY_FILE*)malloc(sizeof(MY_FILE)); 31     if(mf==NULL) 32     { 33         close(fd); //创建结构体失败,关闭文件,返回NULL                    34         return NULL; 35     } 36  37     //4.初始化MY_FILE对象 38     mf->fd = fd; 39     mf->flags=0; 40     mf->flags |= BUFF_LINE; 41     memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer)); 42     mf->current=0; 43     //mf->outputbuffer[0]=0; //初始化缓冲区 44      45     //5.返回打开的文件 46     return mf; 47 } 48  49  50 int my_fflush(MY_FILE* fp) 51 { 52     //将用户层缓冲区中的数据,通过系统调用接口,冲刷给OS 53     assert(fp); 54     write(fp->fd,fp->outputbuffer,fp->current); 55     //... 56     fp->current=0; 57     return 0; 58 } 60 //返回实际写入的字节数 61 size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* stream) 62 { 63     //1.缓冲区如果已经满了,直接写入           64     if(stream->current==NUM)my_fflush(stream); 65      66     //2.根据缓冲区剩余情况,进行数据拷贝 67     size_t user_size= size*nmemb; //要写入多少数据 68     size_t my_size=NUM-stream->current; //缓冲区还剩多少空间 69  70     int writen=0; 71     if(my_size>=user_size) 72     { 73         //缓冲区剩余空间可以容纳要写入的数据 74         memcpy(stream->outputbuffer+stream->current,ptr,user_size); 75         //3.更新计数器字段 76         stream->current += user_size; 77         writen=user_size; 78     }else 79     { 80         memcpy(stream->outputbuffer+stream->current,ptr,my_size); 81         //3.更新计数器字段 82         stream->current+=my_size; 83         writen=my_size; 84     } 85  86     //3.开始计划刷新87     //不发生刷新的本质就是不进行IO,不进行系统调用,所以my_write函数会调用非常快,数据暂时保存在缓冲区    中 88     //可以在缓冲区积压多份数据,统一进行刷新  本质:就是一次IO可以IO更多的数据,提高IO效率 89     if(stream->flags & BUFF_ALL)               90     { 91         if(stream->current==NUM)my_fflush(stream); //全缓冲 92     }else if(stream->flags & BUFF_LINE) 93     { 94         if(stream->outputbuffer[stream->current-1]=='\0')my_fflush(stream); 95     }else{} 96     return writen; 97 } 98  99 100 int my_fclose(MY_FILE*fp)101 {102     assert(fp);103     //1.冲刷缓冲区104     if(fp->current>0)105     {106         my_fflush(fp);107     }108     //2.关闭文件109     close(fp->fd);110     //3.释放堆空间111     free(fp);112     //4.指针置为NULL 113     fp=NULL;114     return 0;115 }

main.c

  1 #include"mystdio.h"  2 #include<unistd.h>  3 #include<string.h>  4   5 #define MYFILE "log.txt"  6   7 int main()  8 {  9     MY_FILE* fp=my_fopen(MYFILE,"w"); 10     if(fp==NULL)return 1; 11  12  13     const char* msg="hello my write"; 14     int cnt=5; 15     //操作文件 16     while(cnt) 17     { 18         char buffer[1024]; 19         snprintf(buffer,sizeof(buffer),"%s:%d\n",msg,cnt--);               20         size_t size=my_fwrite(buffer,strlen(buffer),1,fp); 21         sleep(1); 22         printf("当前成功写入%lu个字节\n",size); 23     } 24     my_fclose(fp); 25     return 0; 26 }

运行结果
在这里插入图片描述

三、强制刷新内核缓冲区(fsync)

在这里插入图片描述

将文件缓冲区的内容强制刷新到文件中。

来源地址:https://blog.csdn.net/Tianzhenchuan/article/details/132608801

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯