Linux之文件--缓冲区模拟
2026/7/30 12:06:20 网站建设 项目流程

一、头文件设计 my_stdio.h

#pragma once #include<stdio.h> #include<string.h> #include<sys/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 flag=0; int fd=-1; if(strcmp(mode,"r")==0) { flag=O_RDONLY; fd=open(filename,flag); } else if(strcmp(mode,"w")==0) { flag=O_WRONLY|O_CREAT|O_TRUNC; fd=open(filename,flag,MYMODE); } else if(strcmp(mode,"a")==0) { flag=O_WRONLY|O_CREAT|O_APPEND; fd=open(filename,flag,MYMODE); } if(fd<0) return NULL; MYFILE* myfile=(MYFILE*)malloc(sizeof(MYFILE)); myfile->fdir=fd; myfile->flag=flag; myfile->cap=MAXSIZE; myfile->flush_mode=LINEMODE; //默认行缓冲 myfile->pos=0; return myfile; } int myfputs(const char* str,MYFILE* fp ) { if(fp == NULL || str == NULL) return -1; int len = strlen(str); //把字符串拷贝进用户缓冲区 memcpy(fp->outbuffer+fp->pos,str,len); fp->pos += len; //根据缓冲模式判断是否自动刷新 if(fp->flush_mode==LINEMODE) { if(fp->outbuffer[fp->pos-1]=='\n') { myfflush(fp); } } else if(fp->flush_mode==FULLMODE) { myfflush(fp); } else if(fp->flush_mode==NONEMODE) { 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

#include<stdio.h> #include"my_stdio.h" #include<unistd.h> int main() { MYFILE* fp=myopen("ss.txt","w"); if(fp==NULL) { printf("打开文件失败\n"); return -1; } int cnt=10; const char* msg="hello 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 写入文件。 直到两种情况触发刷新:

  1. 主动调用myfflush(fp)
  2. myclose(fp)执行,内部强制调用myfflush

如果字符串末尾加上\n,行缓冲会立刻自动刷新,数据马上落到内核缓冲区。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询