1. 程式人生 > >九、文件IO——案例構建標準庫

九、文件IO——案例構建標準庫

緩存滿 文件中 不能 調試 extc reat 字符 c++ color

例子如下:

  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 }

  編譯調試:

  技術分享圖片

九、文件IO——案例構建標準庫