例子如下:

  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——案例构建标准库的更多相关文章

  1. 比较两个文件的异同Python3 标准库difflib 实现

    比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...

  2. 文件IO函数和标准IO库的区别

    摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...

  3. (九)errno和perror、标准IO

    3.1.6.文件读写的一些细节3.1.6.1.errno和perror(1)errno就是error number,意思就是错误号码.linux系统中对各种常见错误做了个编号,当函数执行错误时,函数会 ...

  4. 文件的概念、标准IO其一

    1.文件的概念 文件是一种存储在磁盘(掉电不丢失存储设备)上,掉电不丢失的一种存储数据的方式,文件在系统中有以下层次的结构来实现. 系统调用.文件IO.标准IO的关系如下: 2.linux系统的文件分 ...

  5. 标准io与文件io

    A: 代码重复: 语句块1: while(判断) { 语句块2: 语句块1: } 上面可以改写为: while(1) { 语句块1: if(判断) break: 语句块2: } B: 标准IO和文件I ...

  6. C++标准库头文件找不到的问题

    当你写C++程序时,在头文件中包含C++标准库的头文件,比如#include <string>,而编译器提示你找不到头文件! 原因就是你的实现源文件扩展名是".c"而不 ...

  7. windows下的c语言和linux 下的c语言以及C标准库和系统API

    1.引出我们的问题? 标准c库都是一样的!大家想必都在windows下做过文件编程,在linux下也是一样的函数名,参数都一样.当时就有了疑问,因为我们非常清楚 其本质是不可能一样的,源于这是俩个操作 ...

  8. C++标准库和stl差别

    C++库文件夹:开发工具和语言-visual studio文档-visual C++-參考信息-库參考-standard C++ library C#库文件夹:C#使用.NET Framework 类 ...

  9. 文件I/O和标准I/O

    转载:https://blog.csdn.net/kyang_823/article/details/79496561 一.文件I/O和标准I/O文件I/O:文件I/O也称为不带缓冲的I/O(unbu ...

随机推荐

  1. shell中,2>&1详解

    我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令.首先我们把这条命令大概分解下,首先就是一个nohup表示当前用户和系 ...

  2. luogu2282/bzoj1219 历史年份 (dp+hash+二分+线段树)

    luogu1415 拆分数列的加强版 先考虑弱化版怎么做 设f[i]表示某一串数,最后一个数的右端点是i时,它的左端点的最大值(也就是说,这一串数的最后一个数尽量小) 那么有$f[j]=max\{i+ ...

  3. 利用mysqldump命令导出为csv格式文件

    解决方法: 先导出为txt文件,其内容是以逗号“,”分隔的,得到txt文件后,再自行处理为.csv或者.xls文件. 参数说明: -t, --no-create-info   Don't write ...

  4. nginx日志文件的定时切割与归纳

    应用环境:生产环境中的Nginx服务器,由于访问日志文件增长速度非常快,日志太大会严重影响服务器效率.同时,为了 方便对日志进行分析计算,须要对日志文件进行定时切割.定时切割的方式有按月切割.按天切割 ...

  5. pycharm安装TensorFlow

    一.首先说下我在安装TensorFlow的过程中遇到的坑: 1.python的版本是3.5的版本,因为TensorFlow好像只支持到3.5现在.然后python需要安装64位的安装包,如果安装的是3 ...

  6. css 选择其父元素下的某个元素

    一,选择器 :first-child   p:first-child(first第一个 child子元素)(找第一个子元素为p) :last-child    p:last-child(last倒数 ...

  7. Linux下Chrome/Chromium窗口边框有白线

    原因 窗口边框有白线是因为没有开启使用系统边框和标题栏 解决方法 勾选菜单-设置-外观-使用系统标题栏和边框 效果展示

  8. c 结构体 & 函数指针模拟实现一个java class(类) 和方法

    闲来无事,纯粹练习. student.h #ifndef STUDENT_H_INCLUDED #define STUDENT_H_INCLUDED #include <memory.h> ...

  9. jquery属性操作,应用,事件,扩展extend,动画效果(二)

    一.相关知识点总结1.CSS .css()      - .css("color")  -> 获取color css值 - .css("color", & ...

  10. Hibernate3 多对多关系

    学习hibernate的笔迹第三篇,主要内容:多对多关系, 检索策略,HQL查询,QBC,事物管理,c3p0配置 1.1.1  Hibernate的关联关系映射:(多对多) 1.1.1.1     多 ...