缓冲区的理解和实现

缓冲区的相关理解以及概念、

模拟C语言库的缓冲区和文件相关封装的实现:

Mystdio.c文件:

cpp 复制代码
#define FILE_MODE 0666

_FILE* _fopen(const char *filename, const char *flag)
{
        assert(filename);
        assert(flag);

        int mode = 0;
        size_t fd = -1;
        //判断打开方式,模拟w、a、r
        if(strcmp(flag,"w") == 0)
        {
                //设置文件权限
                mode = (O_CREAT|O_WRONLY|O_TRUNC);
                //打开文件
                fd = open(filename,mode,FILE_MODE);
        }
        else if(strcmp(flag,"a") == 0)
        {
                mode = (O_CREAT|O_WRONLY|O_APPEND);
                fd = open(filename,mode,FILE_MODE);
        }
        else if(strcmp(flag,"r") == 0)
        {
                mode = O_RDONLY;
                fd = open(filename,mode);
        }
        else
        {
                return NULL;
        }

        //有可能文件都没打开
        if(fd == -1)
        {
                return NULL;
        }

        //把fd放到_FILE结构体对象中
        _FILE* fp = (_FILE*)malloc(sizeof(_FILE));
        if(fp == NULL)
        {
                perror("malloc fail");
                return NULL;
        }

        fp->fileno = fd;
        fp->flag = FLUSH_LINE;//行刷新
        fp->out_pos = 0;

        return fp;

}

int _fwrite(_FILE *fp, const char *s, int len)
{
        //将s拷贝到缓冲区中
        memcpy(&fp->outbuffer[fp->out_pos],s,len);
        fp->out_pos += len;

        //判断刷新方式  
        if(fp->flag & FLUSH_NOW)
        {
                //立即刷新
                write(fp->fileno,fp->outbuffer,fp->out_pos);
                fp->out_pos = 0;
        }
        else if(fp->flag & FLUSH_LINE)
        {
                //行刷新
                if(fp->outbuffer[fp->out_pos] == '\n')
                {
                        write(fp->fileno,fp->outbuffer,fp->out_pos);
                        fp->out_pos = 0;
                }
                else
                {
                        return len;
                }
        }
        else if(fp->flag & FLUSH_ALL)
        {
                //全缓冲
                if(fp->out_pos == SIZE)
                {
                        write(fp->fileno,fp->outbuffer,fp->out_pos);
                        fp->out_pos = 0;
                }
                else
                {
                        return len;
                }
        }



}

void _fflush(_FILE *fp)
{
        if(fp->out_pos > 0)
        {
                write(fp->fileno,fp->outbuffer,fp->out_pos);
                fp->out_pos = 0;
        }

}

void _fclose(_FILE *fp)
{
        if(fp == NULL)
        {
                return ;
        }

        _fflush(fp);


        close(fp->fileno);
        free(fp);

}

Mystdio.h文件:

cpp 复制代码
#ifndef __MYSTDIO_H__
#define __MYSTDIO_H__


#include<string.h>

#define SIZE 1024

#define FLUSH_NOW 1
#define FLUSH_LINE 2
#define FLUSH_ALL 4

typedef struct IO_FILE
{
        int fileno;//文件描述符
        int in_pos;//缓冲区已经写了多少
        char inbuffer[SIZE];//输入缓冲区
        int out_pos;//缓冲区已经写了多少
        char outbuffer[SIZE];//输出缓冲区
        int flag;//刷新方式
}_FILE;
void _fflush(_FILE *fp);
_FILE* _fopen(const char *filename, const char *flag);
int _fwrite(_FILE *fp, const char *s, int len);
void _fclose(_FILE *fp);


#endif

测试main.c文件:

cpp 复制代码
#include "Mystdio.h"

int main()
{
        _FILE *fp = _fopen("test.txt","a");
        if(fp == NULL)
        {
                return 1;
        }

        const char *message = "I miss you\n";
        _fwrite(fp,message,strlen(message));

        _fflush(fp);

        _fclose(fp);
        return 0;
}
相关推荐
ji_shuke3 分钟前
远程排查 Web 系统问题:如何导出 HAR 文件协助定位
前端·问题排查
卷无止境7 分钟前
Python 异常处理:从入门到工程实践
后端·python
garuda herb9 分钟前
生成专题页Blog--建立并返回 MySQL 数据库连接
python·mysql
学计算机的计算基10 分钟前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
ONE_SIX_MIX13 分钟前
qwenpaw-plugin-file-tools QwenPaw增强文件工具 更新 v1.1.1
python·qwenpaw
tachibana215 分钟前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode
AOwhisky17 分钟前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算
小保CPP19 分钟前
OpenCV C++提取webp动图里的图片
c++·人工智能·opencv·计算机视觉
不会就选b24 分钟前
linux之进程管理(二)--替换
linux·运维·服务器
倔强的石头10629 分钟前
【Linux指南】动静态库系列(二):从源码复用到目标文件复用:为什么需要把 .o 打包成库
linux·运维·服务器