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

例子如下:

  mystdio.h

 #ifndef __MYSTDIO_H__
#define __MYSTDIO_H__ #include <sys/types.h> #define MYEOF -1 enum mode{READ, WRITE, APPEND}; typedef struct {
int _fd;
char *_buff;
char *_nextc;
int _mode;
off_t _left;
}MYFILE; extern MYFILE * myfopen(const char * const pathname, const char * const mode); extern int myfclose(MYFILE *fp); extern void myfflush(MYFILE *fp); extern MYFILE* myfdopen(int fd, const char * const mode); extern int myfgetc(MYFILE *fp); extern int myfputc(int character, MYFILE *fp); #endif

  mystdio.c

 #include "mystdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <malloc.h>
#include <memory.h> #define BUFFER_LEN 4096 MYFILE * myfopen(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, );
} else if(!strcmp(mode, "a")) {
fd = open(pathname, O_WRONLY | O_CREAT | O_APPEND, );
} else {
return NULL;
} if(fd < )
return NULL; return myfdopen(fd, mode);
} int myfclose(MYFILE *fp)
{
myfflush(fp);
int ret = close(fp->_fd);
free(fp->_buff);
free(fp);
return ret;
} void myfflush(MYFILE *fp)
{
if(fp->_mode == READ) {
fp->_nextc = fp->_buff;//指向缓存开始地址
fp->_left = ;
} else {// write or append
write(fp->_fd, fp->_buff,(BUFFER_LEN - fp->_left));
fp->_nextc = fp->_buff;
fp->_left = BUFFER_LEN;
}
} MYFILE* myfdopen(int fd, const char * const mode)
{
MYFILE *fp = (MYFILE *)malloc(sizeof(MYFILE));//堆中创建fp
assert(fp != NULL);//断言,即保证fp不能为空,为空就在这里跳出 fp->_buff = (char *)malloc(BUFFER_LEN);
assert(fp->_buff != NULL);
fp->_fd = fd;
fp->_nextc = fp->_buff;//nextc 指向缓存中第一个字节
if(!strcmp(mode, "r")) {
fp->_mode = READ;
fp->_left = ;//缓存没有任何数据可读
} if(!strcmp(mode, "w")) {
fp->_mode = WRITE;
fp->_left = BUFFER_LEN;//缓存的大小长度
} if(!strcmp(mode, "w")) {
fp->_mode = APPEND;
fp->_left = BUFFER_LEN;
} return fp;
} int myfgetc(MYFILE *fp)
{
assert(fp->_mode == READ); //当缓存中的数据已经读取完毕,再从文件中读取一批新的数据放入到缓存当中
if(fp->_left == ) {
ssize_t size = read(fp->_fd, fp->_buff, BUFFER_LEN);
assert(size >= );
if(size == ) return MYEOF;
fp->_nextc = fp->_buff;
fp->_left = size;
} char c = *(fp->_nextc);
fp->_nextc++;
fp->_left--; return c;
} int myfputc(int character, MYFILE *fp)
{
assert(fp->_mode == WRITE || fp->_mode == APPEND); //若缓存满,将缓存中的数据写入到文件中
if(fp->_left == ) {
if(write(fp->_fd, fp->_buff, BUFFER_LEN) != BUFFER_LEN) {
return ;
} fp->_nextc = fp->_buff;
fp->_left = BUFFER_LEN;
} // 将字符写入到缓存制定的位置
*(fp->_nextc) = (char)character;
fp->_nextc++;
fp->_left--; return ;
}

  mystdio_test.c

 #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include "mystdio.h" int main(int argc, const char *argv[])
{
MYFILE *fp1 = myfopen("/etc/passwd", "r");
assert(fp1 != NULL);
MYFILE *fp2 = myfopen("mypasswd", "w");
assert(fp2 != NULL); char c;
while((c = myfgetc(fp1)) != MYEOF)
{
myfputc(c, fp2);
} myfclose(fp1);
myfclose(fp2);
return ;
}

  编译调试:

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

上一篇:eclipse里maven项目An error occurred while filtering resources解决办法(转载)


下一篇:介绍一款原创的四则运算算式生成器:CalculateIt2