九、文件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——案例构建标准库的更多相关文章
- 比较两个文件的异同Python3 标准库difflib 实现
比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...
- 文件IO函数和标准IO库的区别
摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...
- (九)errno和perror、标准IO
3.1.6.文件读写的一些细节3.1.6.1.errno和perror(1)errno就是error number,意思就是错误号码.linux系统中对各种常见错误做了个编号,当函数执行错误时,函数会 ...
- 文件的概念、标准IO其一
1.文件的概念 文件是一种存储在磁盘(掉电不丢失存储设备)上,掉电不丢失的一种存储数据的方式,文件在系统中有以下层次的结构来实现. 系统调用.文件IO.标准IO的关系如下: 2.linux系统的文件分 ...
- 标准io与文件io
A: 代码重复: 语句块1: while(判断) { 语句块2: 语句块1: } 上面可以改写为: while(1) { 语句块1: if(判断) break: 语句块2: } B: 标准IO和文件I ...
- C++标准库头文件找不到的问题
当你写C++程序时,在头文件中包含C++标准库的头文件,比如#include <string>,而编译器提示你找不到头文件! 原因就是你的实现源文件扩展名是".c"而不 ...
- windows下的c语言和linux 下的c语言以及C标准库和系统API
1.引出我们的问题? 标准c库都是一样的!大家想必都在windows下做过文件编程,在linux下也是一样的函数名,参数都一样.当时就有了疑问,因为我们非常清楚 其本质是不可能一样的,源于这是俩个操作 ...
- C++标准库和stl差别
C++库文件夹:开发工具和语言-visual studio文档-visual C++-參考信息-库參考-standard C++ library C#库文件夹:C#使用.NET Framework 类 ...
- 文件I/O和标准I/O
转载:https://blog.csdn.net/kyang_823/article/details/79496561 一.文件I/O和标准I/O文件I/O:文件I/O也称为不带缓冲的I/O(unbu ...
随机推荐
- BZOJ2839集合计数
题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是质数喔~ ...
- Manthan, Codefest 18 (rated, Div. 1 + Div. 2) C D
C - Equalize #include<bits/stdc++.h> using namespace std; using namespace std; string a,b; int ...
- FastDFS 文件上传工具类
FastDFS文件上传工具类 import org.csource.common.NameValuePair; import org.csource.fastdfs.ClientGlobal; imp ...
- Django(二十)model中的 class Meta
https://www.cnblogs.com/tongchengbin/p/7670927.html class Main(models.Model): img = models.CharField ...
- vue学习(3)
回顾昨天内容 1.let和const 2.模板字符串 `` 插变量${变量名} 3.箭头函数 function(){} == ()=>{} 1.this的指向问题 2.arguments不能使用 ...
- mybatis的一些小知识
<update id="setReaded"> update wa_ent_job_app set IS_READ= 1, READ_TIME=now() where ...
- bzoj 4326: NOIP2015 运输计划(二分+树链剖分)
传送门 题解: 树链剖分快速求解任意两点间的路径的权值和: 然后,二分答案: 此题的难点是如何快速求解重合路径? 差分数组可以否??? 在此之前先介绍一下相关变量: int fa[maxn]; int ...
- FineUILearning
一:表单控件的学习: 1(1) <f:PageManager > 将对象引用设置到对象的实例,否则页面无法显示: (2)<Menu></Menu>就是下拉菜单控件 ...
- 点赞功能与redis
转:https://edu.aliyun.com/a/20538 摘要: 前言点赞其实是一个很有意思的功能.基本的设计思路有大致两种, 一种自然是用mysql等数据库直接落地存储, 另外一种就是利用点 ...
- (最小生成树 Prim) nyoj1403-沟通无限校园网
题目描述: 校园网是为学校师生提供资源共享.信息交流和协同工作的计算机网络.校园网是一个宽带.具有交互功能和专业性很强的局域网络.如果一所学校包括多个学院及部门,也可以形成多个局域网络,并通过有线或无 ...