首页
最新活动
服务器租用
香港服务器租用
台湾服务器租用
美国服务器租用
日本服务器租用
新加坡服务器租用
高防服务器
香港高防服务器
台湾高防服务器
美国高防服务器
裸金属
香港裸金属服务器
台湾裸金属服务器
美国裸金属服务器
日本裸金属服务器
新加坡裸金属服务器
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
CDN
CDN节点
CDN带宽
CDN防御
CDN定制
行业新闻
官方公告
香港服务器资讯
帮助文档
wp博客
zb博客
服务器资讯
联系我们
关于我们
机房介绍
机房托管
登入
注册
帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
联系客服
服务器资讯
/
香港服务器租用
/
香港VPS租用
/
香港云服务器
/
美国服务器租用
/
台湾服务器租用
/
日本服务器租用
/
官方公告
/
帮助文档
【创作赢红包】- 【Linux】 基础IO——自己实现文件接口FILE
发布时间:2024-03-10 17:16:49 分类:帮助文档
【创作赢红包】| 【Linux】 基础IO——自己实现文件接口FILE 文章目录 1. 创建makefile2. mystdio.h ——接口的声明3. mystdio.c —— 接口的实现1. MY_fopen的实现1.识别标志位2. 尝试打开文件3. 给用户返回MY_FILE对象,需要先创建对象4.初始化MY_FILE对象5.返回打开的文件 2.MY_close 的实现冲刷缓冲区 3. MY_fwrite的实现1.缓冲区如果已经满了,就直接写入流中2.根据缓冲区剩余情况,进行拷贝3. 开始计划刷新对之前内容清空 4. 整体代码1. main.c2. mystdio.h3. mystdio.c 模仿C库,自己封装一个最简单的文件接口 FILE 1. 创建makefile 创建makefile testfile: main.c mystdio.c gcc -o $@ $^ .PHONY:clean clean: rm -f testfile 2. mystdio.h ——接口的声明 创建MY_FILE结构体 内部包含文件描述符fd,输出缓冲区ou’tputbuffer 、flags刷新方法 分别通过C库中fopen 、fwrite、fclose 接口的实现,设计属于自己的接口 3. mystdio.c —— 接口的实现 1. MY_fopen的实现 1.识别标志位 分别实现了读、写追加方式 2. 尝试打开文件 若想打开文件,需要调用open函数 若需要创建文件,则需调用第二个open函数 由于open中的mode参数受umask影响,所以设置一个默认的mode 若不需要创建文件,则调用第一个open函数 3. 给用户返回MY_FILE对象,需要先创建对象 判断对象是否创建成功,若失败需要将文件关闭 4.初始化MY_FILE对象 将自己设置的结构体MY_FILE内部的fd赋值为 open函数打开的返回值fd 刷新方法设置成行缓冲 outputbuffer缓冲区中全部初始化为0 current代表缓冲区中没有数据 5.返回打开的文件 当关闭文件的时候,fclose(FILE*) 将C语言当中的文件指针传进来 当关闭文件的时候,C要自己帮助我们进行冲刷缓冲区 为了方便表述,在MY_FILE结构体添加current变量 current代表下次写入时应该写入什么位置 如 outputbuffer中有5个字符 ,对应下标0 1 2 3 4 ,所以cuurrent代表下标5 2.MY_close 的实现 冲刷缓冲区 自己实现一个fflush(刷新缓冲区),叫做MY_fflush 判断缓冲区是否有数据,若有数据就刷新出去 3. MY_fwrite的实现 缓冲区为ptr,单个单元的大小为size,nmemb代表想要写入几个单元,写入对应的流中 实际上是往缓冲区里写的 1.缓冲区如果已经满了,就直接写入流中 刷新流的缓冲区 2.根据缓冲区剩余情况,进行拷贝 共分为两种情况,若剩余空间足够,则调用if语句,将用户从ptr拷贝的数据全部拷贝给缓冲区 同时由于缓冲区加入user_size个字节,要更新current的位置 若剩余空间不足够,则调用else语句,将从ptr拷贝的数据填满剩余空间即可 同时由于缓冲区加入MY_size个字节,要更新current的位置 通过调用sriten 代表实际写了多少字节,为了充当最后的的返回值 3. 开始计划刷新 主要分为全刷新和行刷新两种情况,其他不考虑 全刷新判断缓冲区是否满了,若满了则直接刷新缓冲区 行刷新判断是否遇见\n,若遇见\n则直接刷新缓冲区 对之前内容清空 为了防止出现每次打印都会有之前的内容情况,所以刷新之后要清空 在这种情况下,之前的内容会被打印出来 将current置为0后,下次写入就可以覆盖上次缓冲区内容 4. 整体代码 1. main.c #include"mystdio.h" #include
#include
#define MYFILE "log.txt" int main() { MY_FILE*fp=MY_fopen(MYFILE,"w"); if(fp==NULL) return 1; const char*str="hello world"; int cnt=5; //操作文件 while(1) { char buffer[1024]; snprintf(buffer,sizeof(buffer),"%s:%d\n",str,cnt--); size_t size=MY_fwrite(buffer,strlen(buffer),1,fp); sleep(1); printf("当前成功写入:%lu个字节\n",size); } MY_fclose(fp); return 0; } 2. mystdio.h #include
#define NUM 1024 #define BUFF_NONE 0x1 //表示无缓冲 #define BUFF_LINE 0x2 //行缓冲 #define BUFF_ALL 0x4 //全缓冲 typedef struct MY_FILE { int fd;//文件描述符 int flags;//刷新方法 char outputbuffer[1024];//输出缓冲区 int current; }MY_FILE; MY_FILE *MY_fopen(const char *path, const char *mode);//自己写fopen size_t MY_fwrite(const void *ptr, size_t size, size_t nmemb, MY_FILE *stream);//自己写的fwrite int MY_fclose(MY_FILE *fp);//自己写的fwrite int MY_fflush (MY_FILE*fp);//自己实现的缓冲区 3. mystdio.c #include"mystdio.h" #include
#include
#include
#include
#include
#include
#include
MY_FILE*MY_fopen(const char *path, const char *mode)//自己写fopen { int flag=0; if(strcmp(mode,"r")==0)//说明当前使用读方式打开文件 flag |= O_RDONLY;//读取 else if(strcmp(mode,"w")==0) flag |=(O_CREAT | O_WRONLY | O_TRUNC);//创建文件 以写的方式打开文件 清空文件 else if(strcmp(mode,"a")==0) flag |=(O_CREAT | O_WRONLY | O_APPEND); //创建文件 以写的方式打开文件 追加 else { //其他不考虑 } //2. 尝试打开文件 mode_t m=0666; int fd=0; //flag代表模式 r w a if(flag & O_CREAT) fd=open(path,flag,m); else //说明不需要打开 fd=open(path,flag); if(fd<0)//当前打开文件失败 return NULL; //3.给用户返回MY_FILE对象,需要先进行构建 MY_FILE*mf=(MY_FILE*)malloc(sizeof(MY_FILE)); if(mf==NULL)//申请空间失败 { close(fd);//关闭文件 return NULL; } // 4. 初始化 MY_FILE对象 mf->fd=fd;//将上述的fd传入结构体的fd中 mf->flags=0; mf->flags=BUFF_LINE;//设置成行缓冲 memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer));//将outputbufeer中的内容全部初始化为0 mf->current=0;//代表缓冲区中没有数据 W>} size_t MY_fwrite(const void *ptr, size_t size, size_t nmemb,MY_FILE *stream) { // 1. 缓冲区如果已经满了,就直接写入 if(stream->current == NUM) MY_fflush(stream); // 2. 根据缓冲区剩余情况,进行数据拷贝即可 size_t user_size = size * nmemb; size_t my_size = NUM - stream->current; // 100 - 10 = 90 size_t writen = 0; if(my_size >= user_size) { memcpy(stream->outputbuffer+stream->current, ptr, user_size); //3. 更新计数器字段 stream->current += user_size; writen = user_size; } else { memcpy(stream->outputbuffer+stream->current, ptr, my_size); //3. 更新计数器字段 stream->current += my_size; writen = my_size; } // 4. 开始计划刷新, 他们高效体现在哪里 -- TODO // 不发生刷新的本质,不进行写入,就是不进行IO,不进行调用系统调用,所以MY_fwrite函数调用会非常快,数据会暂时保存在缓冲区中 // 可以在缓冲区中积压多份数据,统一进行刷新写入,本质:就是一次IO可以IO更多的数据,提高IO效率 if(stream->flags & BUFF_ALL) { if(stream->current == NUM) MY_fflush(stream); } else if(stream->flags & BUFF_LINE) { if(stream->outputbuffer[stream->current-1] == '\n') MY_fflush(stream); } else { //TODO } return writen; } int MY_fflush(MY_FILE *fp) { assert(fp); W> int n= write(fp->fd,fp->outputbuffer,fp->current);//将缓冲区中的current个数传入fd中 fp->current=0; return 0; } int MY_fclose(MY_FILE *fp)//自己写的fwrite { assert(fp);//首先要保证fp不为空 //1. 冲刷缓冲区 if(fp->current>0)//说明缓冲区有数据 MY_fflush(fp); //2. 关闭文件 close(fp->fd); //3.释放堆空间 free(fp); //4.指针置为NULL fp=NULL; return 0; }
上一篇
香港服务器托管价格
下一篇
香港游戏代理公司
相关文章
【零难度!2034年幻兽帕鲁服务器一键开服】3次轻点,10秒开启
fpt怎么弄秒赞网
服务器租用有什么好的介绍
windows2012怎么改磁盘名
服务器租用与托管服务
2008r2 iis 怎么放桌面
买的阿里云服务器怎么开通
服务器端口远程怎么看
服务器名词解释
香港云服务器租用推荐
服务器租用资讯
·广东云服务有限公司怎么样
·广东云服务器怎么样
·广东锐讯网络有限公司怎么样
·广东佛山的蜗牛怎么那么大
·广东单位电话主机号怎么填写
·管家婆 花生壳怎么用
·官网域名过期要怎么办
·官网邮箱一般怎么命名
·官网网站被篡改怎么办
服务器租用推荐
·美国服务器租用
·台湾服务器租用
·香港云服务器租用
·香港裸金属服务器
·香港高防服务器租用
·香港服务器租用特价
7*24H在线售后
高可用资源,安全稳定
1v1专属客服对接
无忧退款试用保障
德讯电讯股份有限公司
电话:00886-982-263-666
台湾总部:台北市中山区建国北路一段29号3楼
香港分公司:九龙弥敦道625号雅兰商业二期906室
服务器租用
香港服务器
日本服务器
台湾服务器
美国服务器
高防服务器购买
香港高防服务器出租
台湾高防服务器租赁
美国高防服务器DDos
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
行业新闻
香港服务器租用
服务器资讯
香港云服务器
台湾服务器租用
zblog博客
香港VPS
关于我们
机房介绍
联系我们
Copyright © 1997-2024 www.hkstack.com All rights reserved.