• 九、文件IO——案例构建标准库


    例子如下:

      mystdio.h

     1 #ifndef __MYSTDIO_H__
     2 #define __MYSTDIO_H__
     3 
     4 #include <sys/types.h>
     5 
     6 #define MYEOF -1
     7 
     8 enum mode{READ, WRITE, APPEND};
     9 
    10 typedef struct {
    11     int     _fd;
    12     char     *_buff;
    13     char     *_nextc;
    14     int     _mode;
    15     off_t     _left;
    16 }MYFILE;
    17 
    18 extern MYFILE * myfopen(const char * const pathname, const char * const mode);
    19 
    20 extern int myfclose(MYFILE *fp);
    21 
    22 extern void myfflush(MYFILE *fp);
    23 
    24 extern MYFILE* myfdopen(int fd, const char * const mode);
    25 
    26 extern int myfgetc(MYFILE *fp);
    27 
    28 extern int myfputc(int character, MYFILE *fp);
    29 
    30 #endif

      mystdio.c

      1 #include "mystdio.h"
      2 #include <sys/types.h>
      3 #include <sys/stat.h>
      4 #include <fcntl.h>
      5 #include <unistd.h>
      6 #include <string.h>
      7 #include <errno.h>
      8 #include <stdlib.h>
      9 #include <stdio.h>
     10 #include <fcntl.h>
     11 #include <assert.h>
     12 #include <malloc.h>
     13 #include <memory.h>
     14 
     15 #define BUFFER_LEN         4096
     16 
     17 MYFILE * myfopen(const char * const pathname, const char * const mode)
     18 {
     19     int fd;
     20     if(!strcmp(mode, "r")) {
     21         fd = open(pathname, O_RDONLY);
     22     } else if(!strcmp(mode, "w")) {
     23         fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC, 0777);
     24     } else if(!strcmp(mode, "a")) {
     25         fd = open(pathname, O_WRONLY | O_CREAT | O_APPEND, 0777);
     26     } else { 
     27         return NULL;
     28     }
     29 
     30     if(fd < 0)
     31         return NULL;
     32 
     33     return myfdopen(fd, mode);
     34 }
     35 
     36 int myfclose(MYFILE *fp)
     37 {
     38     myfflush(fp);
     39     int ret = close(fp->_fd);
     40     free(fp->_buff);
     41     free(fp);
     42     return ret;
     43 }
     44 
     45 void myfflush(MYFILE *fp)
     46 {
     47     if(fp->_mode == READ) {
     48         fp->_nextc = fp->_buff;//指向缓存开始地址
     49         fp->_left = 0;
     50     } else {// write or append
     51         write(fp->_fd, fp->_buff,(BUFFER_LEN - fp->_left));
     52         fp->_nextc = fp->_buff;
     53         fp->_left = BUFFER_LEN;
     54     }
     55 }
     56 
     57 MYFILE* myfdopen(int fd, const char * const mode)
     58 {
     59     MYFILE *fp = (MYFILE *)malloc(sizeof(MYFILE));//堆中创建fp
     60     assert(fp != NULL);//断言,即保证fp不能为空,为空就在这里跳出
     61 
     62     fp->_buff = (char *)malloc(BUFFER_LEN);
     63     assert(fp->_buff != NULL);
     64     fp->_fd = fd;
     65     fp->_nextc = fp->_buff;//nextc 指向缓存中第一个字节
     66     if(!strcmp(mode, "r")) {
     67         fp->_mode = READ;
     68         fp->_left = 0;//缓存没有任何数据可读
     69     }
     70 
     71     if(!strcmp(mode, "w")) {
     72         fp->_mode = WRITE;
     73         fp->_left = BUFFER_LEN;//缓存的大小长度
     74     }
     75 
     76     if(!strcmp(mode, "w")) {
     77         fp->_mode = APPEND;
     78         fp->_left = BUFFER_LEN;
     79     }
     80 
     81     return fp;
     82 }
     83 
     84 int myfgetc(MYFILE *fp)
     85 {
     86     assert(fp->_mode == READ);
     87 
     88     //当缓存中的数据已经读取完毕,再从文件中读取一批新的数据放入到缓存当中
     89     if(fp->_left == 0) {
     90         ssize_t size = read(fp->_fd, fp->_buff, BUFFER_LEN);
     91         assert(size >= 0);
     92         if(size == 0) return MYEOF;
     93         fp->_nextc = fp->_buff;
     94         fp->_left = size;
     95     }
     96 
     97     char c = *(fp->_nextc);
     98     fp->_nextc++;
     99     fp->_left--;
    100 
    101     return c;
    102 }
    103 
    104 int myfputc(int character, MYFILE *fp)
    105 {
    106     assert(fp->_mode == WRITE || fp->_mode == APPEND);
    107 
    108     //若缓存满,将缓存中的数据写入到文件中
    109     if(fp->_left == 0) {
    110         if(write(fp->_fd, fp->_buff, BUFFER_LEN) != BUFFER_LEN) {
    111             return 0;
    112         }
    113 
    114         fp->_nextc = fp->_buff;
    115         fp->_left = BUFFER_LEN;
    116     }
    117 
    118     // 将字符写入到缓存制定的位置
    119     *(fp->_nextc) = (char)character;
    120     fp->_nextc++;
    121     fp->_left--;
    122 
    123     return 1;
    124 }

      mystdio_test.c

     1 #include <sys/types.h>
     2 #include <sys/stat.h>
     3 #include <fcntl.h>
     4 #include <unistd.h>
     5 #include <string.h>
     6 #include <errno.h>
     7 #include <stdlib.h>
     8 #include <stdio.h>
     9 #include <fcntl.h>
    10 #include <assert.h>
    11 #include "mystdio.h"
    12 
    13 int main(int argc, const char *argv[])
    14 {
    15     MYFILE *fp1 = myfopen("/etc/passwd", "r");
    16     assert(fp1 != NULL);
    17     MYFILE *fp2 = myfopen("mypasswd", "w");
    18     assert(fp2 != NULL);
    19 
    20     char c;
    21     while((c = myfgetc(fp1)) != MYEOF)
    22     {
    23         myfputc(c, fp2);
    24     }
    25 
    26     myfclose(fp1);
    27     myfclose(fp2);
    28     return 0;
    29 }

      编译调试:

      

  • 相关阅读:
    知道这几 个正则表达式,能让你少写 1,000 行代码
    移除手机端a标签点击自动出现的边框和背景
    CSS 元素垂直居中的 6种方法
    当文本超出时出现省略号
    css清除select的下拉箭头样式
    设置透明边框
    js 输出语句document.write()及动态改变元素中内容innerHTML的使用
    LOCAL_EXPORT_××用法
    sprd测试系统跑vts
    C++ const用法
  • 原文地址:https://www.cnblogs.com/kele-dad/p/9048718.html
Copyright © 2020-2023  润新知