• 第3章 文件I/O(8)_贯穿案例:构建标准IO函数库


    9. 贯穿案例:构建标准IO函数库

    //mstdio.h

    #ifndef __MSTDIO_H__
    #define __MSTDIO_H__
    
    #include <unistd.h>
    
    #define MEOF  -1   //定义文件末尾标志
    
    //文件读写模式
    enum mode{READ, WRITE, APPEND};
    
    //MFILE结构体
    typedef struct
    {
        int     _fd;
        char*   _buffer; //缓冲区
        char*   _nextc;  //下一个字符
        int     _mode;   //读写模式
        off_t   _left;   //剩余多少字节(对于读表示缓冲区中未读的
                         //字节数对于写,表示缓冲区还剩的空闲空间)
    }MFILE, *PMFILE;
    
    extern MFILE*   mfopen(const char* const pathname, const char* const mode);
    extern int      mfclose(MFILE* fp);
    extern void     mfflush(MFILE* fp);
    extern MFILE*   mfdopen(int fd, const char* const mode);
    extern int      mfgetc(MFILE* fp);
    extern int      mfputc(int character, MFILE* fp);
    extern int      mungetc(int character, MFILE* fp);
    extern char*    mfgets(char* buff, int size, MFILE* fp);
    extern int      mfputs(char* buff, MFILE* fp);
    extern size_t   mfread(void* buff, size_t size, size_t counter, MFILE* fp);
    extern size_t   mfwrite(void* buff, size_t size, size_t counter, MFILE* fp);
    
    #endif

    //mstdio.c

    #include "mstdio.h"
    #include <assert.h>
    #include <string.h>
    #include <fcntl.h>
    #include <malloc.h>
    
    #define BUFFER_LEN  1024
    
    MFILE*   mfopen(const char* const pathname, const char* const mode)
    {
        int fd;
        
        if(!strcmp(mode, "r")){
            fd = open(pathname, O_RDONLY);
        }else if(!strcmp(mode, "w")){
            fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC, 0777);
        }else if(!strcmp(mode, "a")){
            fd = open(pathname, O_WRONLY | O_CREAT | O_APPEND, 0777);
        }else{
            return NULL;
        }
        
        if (fd < 0)  return NULL;
    
        return mfdopen(fd, mode);
    }
    
    int      mfclose(MFILE* fp)
    {
         mfflush(fp);  //先刷新缓存
    
         int ret = close(fp->_fd);
    
         free(fp->_buffer);
         free(fp);
    
         return ret;
    }
    
    void     mfflush(MFILE* fp)
    {
        if(fp->_mode = READ){
            fp->_nextc = fp->_buffer;
            fp->_left = 0;
        }else{  //WRITE or APPEND
            write(fp->_fd, fp->_buffer, (BUFFER_LEN - fp->_left));
            
            fp->_nextc = fp->_buffer;
            fp->_left = BUFFER_LEN;
        }
    
    
    }
    
    
    MFILE*   mfdopen(int fd, const char* const mode)
    {
        MFILE* fp = (MFILE*)malloc(sizeof(MFILE));
        assert( fp != NULL);   //断言fp存在
        
        fp->_buffer = (char*)malloc(BUFFER_LEN); //创建缓冲区
        assert(fp->_buffer != NULL);
    
        fp->_fd = fd;
        fp->_nextc = fp->_buffer;  //初始化,指向缓冲区开始处
    
        if(!strcmp(mode, "r")){
            fp->_mode = READ;
            fp->_left = 0; //缓冲区剩余0字节未读取,即全部读完。
        }
    
        if(!strcmp(mode, "w")){
            fp->_mode = WRITE;
            fp->_left = BUFFER_LEN; //缓冲区剩BUFFER_LEN未写,即空的
        }
    
        if(!strcmp(mode, "a")){
            fp->_mode = APPEND;
            fp->_left = BUFFER_LEN;
        }
    
        return fp;
    }
    
    int      mfgetc(MFILE* fp)
    {
        assert(fp->_mode == READ);  //只允许读操作
    
        //当缓存中的数据己读取完毕,先从文件中读取一批新的数据
        //存入缓存中
        if (fp->_left == 0){
            ssize_t size = read(fp->_fd, fp->_buffer, BUFFER_LEN);
    
            assert( size >=0 );
            
            if(size == 0) return MEOF;
    
            fp->_nextc = fp->_buffer;
            fp->_left = size;
        }
    
        char c = *(fp->_nextc);
        fp->_nextc++;
        fp->_left--;
    
        return c;
    }
    
    int      mfputc(int character, MFILE* fp)
    {
        assert(fp->_mode == WRITE || fp->_mode == APPEND);
    
        //若缓存己满,则先将缓存中的数据写入到文件中
        if(fp->_left == 0){
            if(write(fp->_fd, fp->_buffer, BUFFER_LEN) != BUFFER_LEN){
                return 0;
            }
            
            fp->_nextc = fp->_buffer;
            fp->_left = BUFFER_LEN;
        }
    
        *(fp->_nextc) = (char)character;
        fp->_nextc++;
        fp->_left--;
    
        return 1; //返回成功写入的字符个数
    }
    
    int      mungetc(int character, MFILE* fp)
    {
        int ret = 0;
    
        return ret;
    }
    
    char*    mfgets(char* buff, int size, MFILE* fp)
    {
        char* ret = NULL;
    
        return ret;
    }
    
    int      mfputs(char* buff, MFILE* fp)
    {
        int ret = 0;
    
        return ret;
    }
    
    size_t   mfread(void* buff, size_t size, size_t counter, MFILE* fp)
    {
        size_t ret = 0;
    
        return ret;
    }
    
    size_t   mfwrite(void* buff, size_t size, size_t counter, MFILE* fp)
    {
        size_t ret = 0;
    
        return ret;
    }

    //mstdio_test.c

    #include "mstdio.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    int main(int argc, char* argv[])
    {
    
        MFILE* fp1 = mfopen("/etc/passwd", "r");
        assert(fp1 != NULL);
    
        MFILE* fp2 = mfopen("mypasswd", "w");
        assert( fp2 != NULL);
        
        char c;
        while((c=mfgetc(fp1)) != MEOF){
            mfputc(c, fp2); 
        }
    
        mfclose(fp1);
        mfclose(fp2);
    
        return 0;
    }
  • 相关阅读:
    js实现点击隐藏图片
    绝对定位给图片四角加上图片修饰
    雪碧图实现登陆页面
    弹性盒模型
    数组练习--求数组和,平均值,最大值,最小值
    h5与c3权威指南笔记--css3结构性伪类选择器root,not,empty,target
    h5与c3权威指南笔记--css3新属性选择器
    闲聊Java里的随机数
    Python之简单抓取豆瓣读书信息
    中本聪比特币论文
  • 原文地址:https://www.cnblogs.com/5iedu/p/6345093.html
Copyright © 2020-2023  润新知