九、文件IO——案例構建標準庫
阿新 • • 發佈:2018-05-19
緩存滿 文件中 不能 調試 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(intcharacter, 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——案例構建標準庫