zoukankan      html  css  js  c++  java
  • 第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;
    }
  • 相关阅读:
    jq绑定事件
    NReco.PdfGenerator HtmlToPdfConverter 使用示例(未完成)
    msbuild 简单命令
    python 文件操作
    OpenXml demo
    js 常见代码
    C# 静态变量、静态函数、实体变量、实体函数在一个类中的执行顺序
    线程相关技术
    css 光标
    ECMAScript面向对象(二)——之创建对象方法总结
  • 原文地址:https://www.cnblogs.com/5iedu/p/6345093.html
Copyright © 2011-2022 走看看