九、文件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 ...
随机推荐
- Equivalent Sets HDU - 3836 (Tarjan)
题目说给出一些子集,如果A是B的子集,B是A的子集,那么A和B就是相等的,然后给出n个集合m个关系,m个关系表示u是v的子集,问你最小再添加多少个关系可以让这n个集合都是相等的 如果这n个几个都是互相 ...
- 【linux】/dev/null作用和/dev/random
一. /dev/null /dev/null属于字符特殊文件,它属于空设备,是一个特殊的设备文件,它会丢弃一切写入其中的数据,写入它的内容都会永远丢失,而且没有任何可以读取的内容. 我们用file命 ...
- 牛客练习赛40 A 小D的剧场 (思维dp)
链接:https://ac.nowcoder.com/acm/contest/369/A 题目描述 若你摘得小的星星 你将得到小的幸福 若你摘得大的星星 你将得到大的财富 若两者都能摘得 你将得到 ...
- poj 2356 (抽屉原理)
题目链接:http://poj.org/problem?id=2356 题目大意:给你n个数,要你从n个数选出若干个数,要求这若干个数的和是n的倍数,输出选择数的个数,以及相应的数. 解题思路: 以下 ...
- HDU--4486 Task(贪心)
题目链接 4486 Task 按照时间从大到小排序 然后枚举所有的y值 用一个数组存储 符合要求就算上 #include<bits/stdc++.h> using namespace s ...
- 用 Homebrew 带飞你的 Mac
文章目录 资料 安装 基本用法 源镜像 Homebrew也称brew,macOS下基于命令行的最强大软件包管理工具,使用Ruby语言开发.类似于CentOS的yum或者Ubuntu的apt-get,b ...
- Web Deploy 服务器安装设置与使用
一.服务器的安装设置 1.在windows server上确保IIS安装了[管理服务]这个功能.方法是在[服务器管理器]=>[管理]=>[添加角色和功能]=>[下一步]=>[基 ...
- (转)每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)
背景:在redis集群中,有关于一致性哈希的使用. 一致性哈希:桶大小0~(2^32)-1 哈希指标:平衡性.单调性.分散性.负载性 为了提高平衡性,引入“虚拟节点” 每天进步一点点——五分钟理解一致 ...
- Django(四)框架之第三篇模板语法
https://www.cnblogs.com/yuanchenqi/articles/6083427.htm https://www.cnblogs.com/haiyan123/p/7725568. ...
- 关于MySQL锁的详解
有2种 1.表锁 2.行锁 支持 .innodb支持行锁,表级锁 .myisam只支持表级锁 innodb实现了下面2种标准的行级锁 .共享锁 S LOCK 允许事务读一行数据 .排他锁 X LOCK ...