Linux之文件--缓冲区模拟

Linux之文件--缓冲区模拟 一、头文件设计 my_stdio.h#pragma once #includestdio.h #includestring.h #includesys/stat.h #define MAXSIZE 1024 //缓冲区大小 #define NONEMODE 1 //全缓冲缓冲区满才刷新 #define LINEMODE 2 //行缓冲遇到\n自动刷新 #define FULLMODE 3 //无缓冲每次写入立刻刷新 #define MYMODE 0666 //文件创建权限 struct IO_FILE { int flush_mode; //缓冲模式 int flag; //open标志位 int fdir; //文件描述符 char outbuffer[MAXSIZE]; //用户缓冲区 int pos; //缓冲区有效字符偏移 int cap; //缓冲区容量 }; typedef struct IO_FILE MYFILE; MYFILE* myopen(const char* filename,const char* mode); int myfputs(const char* str,MYFILE* fp); void myfflush(MYFILE* stream); void myclose(MYFILE* stream);二、接口实现 my_stdio.c#include string.h #include stdlib.h #include sys/stat.h #include sys/types.h #include fcntl.h #include unistd.h #include my_stdio.h MYFILE* myopen(const char* filename,const char* mode) { int flag0; int fd-1; if(strcmp(mode,r)0) { flagO_RDONLY; fdopen(filename,flag); } else if(strcmp(mode,w)0) { flagO_WRONLY|O_CREAT|O_TRUNC; fdopen(filename,flag,MYMODE); } else if(strcmp(mode,a)0) { flagO_WRONLY|O_CREAT|O_APPEND; fdopen(filename,flag,MYMODE); } if(fd0) return NULL; MYFILE* myfile(MYFILE*)malloc(sizeof(MYFILE)); myfile-fdirfd; myfile-flagflag; myfile-capMAXSIZE; myfile-flush_modeLINEMODE; //默认行缓冲 myfile-pos0; return myfile; } int myfputs(const char* str,MYFILE* fp ) { if(fp NULL || str NULL) return -1; int len strlen(str); //把字符串拷贝进用户缓冲区 memcpy(fp-outbufferfp-pos,str,len); fp-pos len; //根据缓冲模式判断是否自动刷新 if(fp-flush_modeLINEMODE) { if(fp-outbuffer[fp-pos-1]\n) { myfflush(fp); } } else if(fp-flush_modeFULLMODE) { myfflush(fp); } else if(fp-flush_modeNONEMODE) { if(fp-pos fp-cap) { myfflush(fp); } } return len; } void myfflush(MYFILE* fp) { if(fp NULL) return; if(fp-pos 0) return; write(fp-fdir, fp-outbuffer, fp-pos); fp-pos 0; } void myclose(MYFILE* fp) { if(NULL fp) return; myfflush(fp); //关闭文件前强制刷新缓冲区残留数据 close(fp-fdir); free(fp); }三、测试代码 main.c#includestdio.h #includemy_stdio.h #includeunistd.h int main() { MYFILE* fpmyopen(ss.txt,w); if(fpNULL) { printf(打开文件失败\n); return -1; } int cnt10; const char* msghello buffer; while(cnt--) { myfputs(msg,fp); sleep(1); printf(debug:pos%d\n,fp-pos); } myclose(fp); return 0; }四、核心原理讲解1. 缓冲区运行逻辑示例代码默认LINEMODE行缓冲字符串hello buffer不带换行\n 循环写入时数据不断堆积在outbufferpos持续上涨不会自动调用 write 写入文件。 直到两种情况触发刷新主动调用myfflush(fp)myclose(fp)执行内部强制调用myfflush如果字符串末尾加上\n行缓冲会立刻自动刷新数据马上落到内核缓冲区。