模拟实现:glibc_1.0-文件操作函数fopen fclose fwrite fflush实现。

@bit::Shadow
✧(≖ ◡ ≖✿

目录

文件与缓冲区的关系

模拟实现

文件属性

文件库函数

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)结构体:

cpp 复制代码
#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"............

实现:
cpp 复制代码
MyFile* MyFopen (const char *pathname, const char* f);

1.明确打开方式以对文件属性调整。

2.☆☆☆BuyFile()以malloc申请空间。

3.返回MyFile。

MyFile* MyFopen(const char* pathname, const char* f):

cpp 复制代码
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):

cpp 复制代码
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。

cpp 复制代码
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特定类型后的写入数据操作:

cpp 复制代码
//刷新
int MyFflush(MyFile* stream)
{
    if(stream->bufferLen <= 0) return 0;

    //清除缓冲区内容到文件内
    //操作系统只认fd!!
    write(stream->fileNo,stream->outBuffer,stream->bufferLen);
    stream->bufferLen=0;
    return 0;
}

fclose()

☆☆☆清空资源前必先刷新缓冲区:

cpp 复制代码
//Fclose
int MyFclose(MyFile* stream)
{
    //close退出强制刷新缓冲区
    MyFflush(stream);

    close(stream->fileNo);
    //资源释放
    free(stream);
    return 0;
}

感谢观看

求关注

相关推荐
小弥儿20 分钟前
GitHub今日热榜 | 2026-09-18:腾讯双项目上榜
学习·开源
qq_199886871 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
2601_966949651 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_734571762 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
知识分享小能手2 小时前
深度学习学习教程,从入门到精通,深度生成模型 —— 知识点详解与代码实现(20)
人工智能·深度学习·学习
汉克老师3 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者3 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
m4Rk_3 小时前
【论文阅读】Agent 记忆机制(74):CompassMem——从相似度检索走向事件图上的记忆导航
论文阅读·人工智能·学习·开源·github
小李不想当小白3 小时前
DMA直接存储器存取(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·分享
RAN11426760083 小时前
1.3第一个程序的介绍
开发语言·qt