九、文件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 }

  编译调试:

  

 

posted @ 2018-05-18 22:26  游戏进行中  阅读(237)  评论(0编辑  收藏  举报