目录
头文件:
接下来就是设计这四个函数:Mystdio.c
重点讲一讲_fflush函数的底层实现原理:
所以数据内容的经过如下:
总结:
执行——测试写好的这4个函数:
运行结果:
修改测试代码:
运行结果:
回顾上文,我讲述了关于Linux文件系统中关于缓冲区的含义和理解,用一个特殊案例表明了我们所了解到的缓冲区是C语言库函数中特有的,而系统调用函数没有。 此外就是C库缓冲区的刷新策略,共有三种:立即刷新、行缓冲、全缓冲.....
Linux文件系统的缓冲区问题
那么接下来我就根据学到的缓冲区,通过在VIM编译器中自己简单手撕一下四个函数:fopen、fclose、fwrite、fflush函数的底层实现,因为这4个函数都是C库函数,都有缓冲区,那么我们就可以去深入了解一下这些函数到底是怎么做到将内容写入到指定文件中去的。
#include
#include
#include
#include
#include
#include
#include
#include
//定义缓冲区刷新策略
#define cash_now 1 //立即刷新
#define cash_line 2 //行缓冲
#define cash_all 4 //全缓冲
#define SIZE 1024
//重命名结构体
typedef struct _FILE{
int _fileno; //文件描述符
int _flag; //缓冲区刷新策略
int _cap; //缓冲区最大容量
int _size; //当前缓冲区的存在的字节数
char _buf[SIZE]; //缓冲区——数组
}_FILE;
//函数声明
_FILE* _fopen(const char* path,const char* mode);
void _fwrite(void* ptr,int num,_FILE* fp);
void _fclose(_FILE* fp);
void _fflush(_FILE* fp);
因为缓冲区的位置在FILE结构体的内部,我们手撕的话,需要自己创建一个类似FILE的结构体,在该结构体中上面5个是必要的成员变量,_fileno是用于使用系统调用函数open的返回值,_flag可以自己设置缓冲区的刷新策略:cash_now、cash_line、cash_all;_cap和_size就是用于缓冲区的容量和当前值,而最重要的就是_buf缓冲区了。我们写的内容全都要靠它进行传递。
然后我来介绍一下我们要手撕的C库函数:
1.fopen函数用于打开文件,对其进行读/写。
2.fwrite函数用于将写好的内容送入缓冲区中。
3.fflush函数用于强制刷新缓冲区的内容到指定流中。
4.fclose函数用于关闭文件,最终清理缓冲区残留内容。
#include"Mystdio.h"
#include
_FILE* _fopen(const char* path,const char* mode){
int flags=0;
if(strcmp(mode,"r")==0){
flags=flags |O_RDONLY;
}
else if(strcmp(mode,"w")==0){
flags=flags |O_WRONLY |O_CREAT |O_TRUNC;
}
else if(strcmp(mode,"a")==0){
flags=flags | O_WRONLY |O_CREAT |O_APPEND;
}
else{
//剩余的r+,w+,....
}
int power=0666; //设置文件权限
int fd=0; //文件描述符
if(flags& O_RDONLY){ //读文件的文件描述符
fd=open(path,flags);
}
else{ //写文件的文件描述符
fd=open(path,flags,power);
}
//判断文件是否被打开
//情况1:打开文件失败
if(fd<0){
const char* str=strerro