模拟实现:glibc_1.0-文件操作函数fopen fclose fwrite fflush实现。
✧(≖ ◡ ≖✿
目录
文件与缓冲区的关系
模拟实现
文件属性
文件库函数
fopen()
实现:
文件打开会不会发生缓冲区内存在内容?而需要缓冲区刷新?
fwrite()
fflush()
fclose()
复习必看gitee.com
glibc是Linux中使用最广泛最核心的C语言标准库实现。像: printf malloc open strlen等。
模拟实现:使用open write close核心系统调用来实现fopen fwrite fclose fflush。
文件与缓冲区的关系
输入-缓冲区-文件
采用f系列接口,缓冲区是链接stdin与文件的桥梁。
模拟实现
文件属性
为描述文件属性及库函数的便捷实现,创建以struct IO_FILE类型(MyFile)结构体:
#define MAX typedef struct IO_FILE { int fileNo; //fd int flag; //打开模式:O_WRONLY、O_CREAT、O_TRUNC及O_APPEND char outBuffer[MAX] //缓冲区字符数组 int bufferlen; //outBuffer长度 int flushMethod; //刷新方法 }MyFile;注意:typedef的使用格式,typedef将类型“struct IO_FILE”以“MyFile”替代。
文件库函数
fopen()
原型:
FILE* fopen(const char* pathname, const char* mode);
//pathname:绝对路径/相对路径
//mode:"w" "r" "a"…………
实现:
MyFile* MyFopen (const char *pathname, const char* f);1.明确打开方式以对文件属性调整。
2.☆☆☆BuyFile()以malloc申请空间。
3.返回MyFile。
MyFile* MyFopen(const char* pathname, const char* f):
MyFile* MyFopen (const char *pathname, const char* f) { int fd; int flag; // 打开方法定位属性: if(strcmp(f,"r")==0) { fd = open(pathname,O_RDONLY); flag = O_RDONLY; } else if(strcmp(f,"w")==0) { fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC,0666); flag = O_WRONLY | O_CREAT | O_TRUNC; } else if(strcmp(f,"a")==0) { fd = open(pathname, O_APPEND | O_CREAT, 0666); flag = O_APPEND | O_CREAT; } else { printf("该功能未添加\n"); return NULL; } if(fd == -1) { perror("open failed!!\n"); return NULL; } MyFile* file = BuyFile(fd, flag, LINE_FLUSH); if(file == NULL) { perror("MyFopen::BuyFile() failed\n"); return NULL; } return file; }MyFile* BuyFile(int _fileNo, int _flag, _flushMethod):
MyFile* BuyFile(int _fileNo, int _flag, int _flushMethod) { //空间申请!! MyFile* newfile=(MyFile*)malloc(sizeof(MyFile)); if(newfile == NULL) return NULL; //memset()初始化好的习惯 memset(newfile, 0, sizeof(MyFile)); //文件属性设置: newfile->fileNo = _fileNo; newfile->flag = _flag; newfile->flushMethod = _flushMethod; return newfile; }文件打开会不会发生缓冲区内存在内容?而需要缓冲区刷新?
缓冲区有内容<--->写入操作与接下来文件打开的要求矛盾。
fwrite()
1.传参数据拷贝到缓冲区。
☆2.写入完成后是否刷新缓冲区取决于文件打开方式flag。
size_t MyFwrite(const void *ptr, size_t size, size_t nmemb, MyFile *stream) { //1.拷贝到缓冲区 memcpy(stream->outBuffer, ptr, size*nmemb); //bufferlen是字节个数还是元素个数? 肯定是字节个数因为写入文件的全部设置为字符 stream->bufferLen += size*nmemb; //ferite的作用是写入到缓冲区还是写到文件内?明显是写入到缓冲区否则fwrite就没用了。 //要立即刷新缓冲区吗? //刷新缓冲区的目的是拷贝缓冲区内容到文件内 //printf("%d\n",size*nmemb); //缓冲区需要刷新的情况: if((stream->flag & O_TRUNC || stream->flag & O_APPEND) && \ stream->outBuffer[stream->bufferLen-1]=='\n') { printf("缓冲区刷新成功\n"); MyFflush(stream); } return nmemb; }fflush()
fflush是程序退出/fwrite特定类型后的写入数据操作:
//刷新 int MyFflush(MyFile* stream) { if(stream->bufferLen <= 0) return 0; //清除缓冲区内容到文件内 //操作系统只认fd!! write(stream->fileNo,stream->outBuffer,stream->bufferLen); stream->bufferLen=0; return 0; }fclose()
☆☆☆清空资源前必先刷新缓冲区:
//Fclose int MyFclose(MyFile* stream) { //close退出强制刷新缓冲区 MyFflush(stream); close(stream->fileNo); //资源释放 free(stream); return 0; }感谢观看
求关注
