模拟实现: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;
}

感谢观看

求关注

相关推荐
Ulyanov1 小时前
Python实现6-DOF刚体仿真器(下)——环境扰动与控制闭环
开发语言·python·算法·系统仿真·雷达电子对抗·导引头
分布式存储与RustFS1 小时前
RustFS Beta.10 性能解读:PUT 全面反超 MinIO,Rust 重写对象存储成了?
开发语言·后端·rust
Eira-Z1 小时前
git(持续学习中...)
git·学习
小小的木头人1 小时前
Python 批量解析 Excel 经纬度,调用高德地图 API 获取中文地址
开发语言·python·excel
子非鱼94271 小时前
07-Flutter 鸿蒙实战 07:故事集列表与缓存设计
学习·flutter·缓存·华为·harmonyos
fanchenxinok2 小时前
学习笔记:LabVIEW中如何将解析S19/HEX的VI封装为子VI并供主VI调用
笔记·学习·labview·子vi
小保CPP2 小时前
OCR C++ Tesseract生成可搜索的pdf
c++·人工智能·ocr·模式识别·光学字符识别
2301_809051142 小时前
基本电子电路元件 学习笔记
笔记·学习
nzz_1712142 小时前
PHP程序员转型AI岗位指南:核心技能、北京就业市场与转型路径分析
开发语言·人工智能·php
Risehuxyc2 小时前
C# 将doc转换为docx
开发语言·c#·xhtml