例子如下:

  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. RabbitMQ图解

    一.MQ对比 二.RabbitMQ模式 三.队列模式 四.公平分发 五.主题模式

  2. 【转】让浏览器格式化显示JSON数据之chrome jsonView插件安装

    jsonView 用来让Chrome浏览器能格式化的显示JSON数据. 以上是网上找的方式,且试验成功! 步骤: 1.打开 https://github.com : 2.搜索 jsonView 链接: ...

  3. Baker Vai LightOJ - 1071 (MCMF)

    在个给出的矩阵从,从左上角走到右下角,然后再从右下角走到左上角,两次不能经过想同的点,每个点都有一个价值,问最大的价值是多少. 可以把原来的问题化简成从左上角走两条路到右下角,然后把价值加起来,然是这 ...

  4. linux(fedora) 第一课

    1.Linux查看ip地址:ifconfig(interface config) 2.find / -name ifconfig (查找 从/开始找 找名字 匹配ifconfing) 复制命令:Ctr ...

  5. centos7系统安装完成后一些基本的优化

    安装完centos7.3后,做一些基本的操作 基本操作一:主机名 centos7有一个新的修改主机名的命令hostnamectl # hostnamectl set-hostname --static ...

  6. Python学习day3 数据类型Ⅰ(str,int,bool)

    day3  数据类型 @上节内容补充 每周一个思维导图-xmind.exe in / not in #示例:(是否包含敏感字符)while True:    text = input('请输入你要说的 ...

  7. Sublime使用小记

    Jason转换插件: 多行编辑快捷键:Ctrl A全选,再按下 Ctrl Shift L (Command Shift L) 即可同时编辑这些行:鼠标选中文本,反复按 CTRL D (Command ...

  8. sha256加密

    sha256: 1.使用npm安装 :npm install js-sha256 2.然后在组件中methods定义方法,在调用 // sha256加密密码 setSha(){ let sha256 ...

  9. P3486 [POI2009]KON-Ticket Inspector

    啊!这题做的真是爽!除了DP这个方法是有提示的之外,这题居然没有题解,哈哈哈嘿嘿嘿.很自豪的说:全是我自己独立解出来的一道题,包括设计状态,推倒(☺)转移方程,最后记录路径. 好了,首先,我们发现这题 ...

  10. Tree Restoration Gym - 101755F (并查集)

    There is a tree of n vertices. For each vertex a list of all its successors is known (not only direc ...