【lesson37】自己设计用户级缓冲区

文章目录

  • 自己设计用户级缓冲区
    • 简易MyFILE_的结构
    • fopen_的实现
    • fputs_的实现
    • fclose_的实现
    • fflush_的实现
  • 完整版代码

自己设计用户级缓冲区

因为用户缓冲区在FILE中,所以我们直接模仿C语言提供的文件操作接口,顺便实现缓冲区。
使用文件系统的框架:模仿C语言
在这里插入图片描述
下面就是一步一步实现具体的函数。

简易MyFILE_的结构

#define NUM 1024    
    
struct MyFILE_ {    
    int fd;//文件描述符fd    
    char buffer[NUM];//用户级缓冲区    
    int end; //当前缓冲区的结尾    
};

fopen_的实现

typedef struct MyFILE_ MyFILE;

MyFILE* fopen_(const char* pathname, const char* mode)
{
    assert(pathname);
    assert(mode);

    MyFILE* fp = NULL;

    if (strcmp(mode, "w") == 0)
    {
      int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0666);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "w+") == 0)
    {
      int fd = open(pathname,O_RDWR | O_CREAT | O_TRUNC,0666);
      if(fd > 0)
      {                                                                                                                                                                 
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "r") == 0)
    {
      int fd = open(pathname,O_RDONLY);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "r+") == 0)
    {
      int fd = open(pathname,O_RDWR);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "a") == 0)
    {
      int fd = open(pathname,O_WRONLY | O_CREAT | O_APPEND,0666);                                                                                                       
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "a+") == 0)
    {
      int fd = open(pathname,O_RDWR | O_CREAT | O_APPEND,0666);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else {
        //什么都不做
    }

    return fp;
}

fputs_的实现

void fputs_(const char* message, MyFILE* fp)
{                                     
   assert(message);           
   assert(fp); 
   strcpy(fp->buffer+fp->end,message);
   fp->end += strlen(message);
                       
   if(fp->fd == 0) 
   {           
     //标准输入                       
     //不做任何操作
   }                                                                                                                                                                    
   else if(fp->fd == 1)               
   {             
     //标准输出
     write(fp->fd,fp->buffer,fp->end);
     fp->end = 0;
   }
   else if(fp->fd == 2)
   {
     //标准错误
     write(fp->fd,fp->buffer,fp->end);
     fp->end = 0;
   }
   else 
   {
     //其它文件
     //不做任何操作
   }
}

fclose_的实现

void fclose_(MyFILE *fp)
{
    assert(fp);
    //关闭文件之前,把缓冲区的所有内容刷新出去
    fflush_(fp);
    close(fp->fd);
    free(fp);
}

fflush_的实现

void fflush_(MyFILE* fp)
{
  assert(fp);
  if(fp->end != 0)
  {
    //将数据写到内核,并不是立马写到磁盘文件中
    write(fp->fd,fp->buffer,fp->end);

    syncfs(fp->fd);//将数据写到磁盘
    fp->end = 0;
  }
}

完整版代码

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 #include <assert.h>
  8 #include <stdlib.h>
  9 
 10 #define NUM 1024
 11 
 12 struct MyFILE_ {
 13     int fd;
 14     char buffer[NUM];
 15     int end; //当前缓冲区的结尾
 16 };
 17 
 18 typedef struct MyFILE_ MyFILE;
 19 
 20 MyFILE* fopen_(const char* pathname, const char* mode)
 21 {
 22     assert(pathname);
 23     assert(mode);
 24 
 25     MyFILE* fp = NULL;
 26 
 27     if (strcmp(mode, "w") == 0)
 28     {
 29       int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0666);                                                                                                    
 30       if(fd > 0)
 31       {
 32         fp = (MyFILE*)malloc(sizeof(MyFILE));
 33         memset(fp,0,sizeof(MyFILE));
 34         fp->fd = fd;
 35       }
 36     }
 37     else if (strcmp(mode, "w+") == 0)
 38     {
 39       int fd = open(pathname,O_RDWR | O_CREAT | O_TRUNC,0666);
 40       if(fd > 0)
 41       {
 42         fp = (MyFILE*)malloc(sizeof(MyFILE));                                                                                                                       
 43         memset(fp,0,sizeof(MyFILE));
 44         fp->fd = fd;
 45       }
 46     }
 47     else if (strcmp(mode, "r") == 0)
 48     {
 49       int fd = open(pathname,O_RDONLY);
 50       if(fd > 0)
 51       {
 52         fp = (MyFILE*)malloc(sizeof(MyFILE));
 53         memset(fp,0,sizeof(MyFILE));
 54         fp->fd = fd;
 55       }
 56     }
 57     else if (strcmp(mode, "r+") == 0)
 58     {
 59       int fd = open(pathname,O_RDWR);
 60       if(fd > 0)
 61       {
 62         fp = (MyFILE*)malloc(sizeof(MyFILE));
 63         memset(fp,0,sizeof(MyFILE));
 64         fp->fd = fd;
 65       }
 66     }
 67     else if (strcmp(mode, "a") == 0)
 68     {
 69       int fd = open(pathname,O_WRONLY | O_CREAT | O_APPEND,0666);
 70       if(fd > 0)
 71       {
 72         fp = (MyFILE*)malloc(sizeof(MyFILE));                                                                                                                       
 73         memset(fp,0,sizeof(MyFILE));
 74         fp->fd = fd;
 75       }
 76 
 77     }
 78     else if (strcmp(mode, "a+") == 0)
 79     {
 80       int fd = open(pathname,O_RDWR | O_CREAT | O_APPEND,0666);
 81       if(fd > 0)
 82       {
 83         fp = (MyFILE*)malloc(sizeof(MyFILE));
 84         memset(fp,0,sizeof(MyFILE));
 85         fp->fd = fd;
 86       }
 87 
 88     }
 89     else {
 90         //什么都不做
 91     }
 92 
 93     return fp;
 94 }
 95 
 96 void fputs_(const char* message, MyFILE* fp)
 97 {
 98    assert(message);
 99    assert(fp);
100    strcpy(fp->buffer+fp->end,message);
101    fp->end += strlen(message);
102 
103    if(fp->fd == 0)
104    {
105      //标准输入                                                                                                                                                     
106      //不做任何操作
107    }
108    else if(fp->fd == 1)
109    {
110      //标准输出
111      write(fp->fd,fp->buffer,fp->end);
112      fp->end = 0;
113    }
114    else if(fp->fd == 2)
115    {
116      //标准错误
117      write(fp->fd,fp->buffer,fp->end);
118      fp->end = 0;
119    }
120    else 
121    {
122      //其它文件
123      //不做任何操作
124    }
125 }
126 
127 
128 void fflush_(MyFILE* fp)
129 {
130   assert(fp);
131   if(fp->end != 0)
132   {
133     //将数据写到内核,并不是立马写到磁盘文件中
134     write(fp->fd,fp->buffer,fp->end);
135 
136     syncfs(fp->fd);//将数据写到磁盘
137     fp->end = 0;
138   }                                                                                                                                                                 
139 }
140 
141 void fclose_(MyFILE* fp)
142 {
143   assert(fp);
144 
145   fflush_(fp);
146   close(fp->fd);
147   free(fp);
148 }
149 
150 int main()
151 {
152     MyFILE* fp = fopen_("./log.txt", "w");
153     if (fp == NULL)
154     {
155         printf("open file error");
156         return 1;
157     }
158     else 
159     {
160 
161         const char* s = "hello world\n";
162         fputs_(s, fp);
163 
164 
165         fclose_(fp);
166     }
167 
168     return 0;
169 }


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/371309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git rebase # |REBASE 1/1 #rebase in progress; onto

git 代码解决冲突之后会提示rebase in progress; onto 1 执行git rebase --abort 回到没有pull代码之前 2 git pull 3 解决冲突 4 git add . (不需要git commit) 5 git rebase --continue 6 git push

Java实现康复中心管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

【代码随想录-哈希表】两个数组的交集

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

Matplotlib热力图的创意绘制指南【第54篇—python:Matplotlib热力图】

文章目录 Matplotlib热力图的创意绘制指南1. 简介2. 基本热力图3. 自定义颜色映射4. 添加注释5. 不同形状的热力图6. 分块热力图7. 多子图热力图8. 3D热力图9. 高级颜色映射与颜色栏设置10. 热力图的动态展示11. 热力图的交互性12. 标准化数据范围13. 导出热力图 总结&#xff…

【爬虫实战】全过程详细讲解如何使用python获取抖音评论,包括二级评论

简介&#xff1a; 前两天&#xff0c;TaoTao发布了一篇关于“获取抖音评论”的文章。但是之前的那一篇包涵的代码呢仅仅只能获取一级评论。虽然说抖音的一级评论挺精彩的了&#xff0c;但是其实二级评论更加有意思&#xff0c;同时二级评论的数量是很多。所以二级评论是非常值…

适合大型企业的云计算服务器有哪些?

随着云计算技术的不断发展&#xff0c;越来越多的企业开始采用云计算服务来降低成本、提高效率。对于大型企业而言&#xff0c;选择适合的云计算服务器非常重要&#xff0c;因为它将直接影响企业的业务运营和数据安全。本文将介绍适合大型企业的云计算服务器类型&#xff0c;以…

DolphinScheduler实现隔几天调度

1.场景分析 dolphinscheduler&#xff08;海豚&#xff09;定时器模块-定时调度时每3秒|每3分钟|每3天这种定时&#xff0c;不能够跨分钟&#xff0c;跨小时&#xff0c;跨月&#xff0c;每次跨月等都会从每个月的第1天&#xff08;第几天开始可以设定&#xff09;开始重新计时…

java设计模式:观察者模式

在平常的开发工作中&#xff0c;经常会使用到设计模式。合理的使用设计模式&#xff0c;可以提高开发效率、提高代码质量、提高代码的可拓展性和维护性。今天来聊聊观察者模式。 观察者模式是一种行为型设计模式&#xff0c;用于对象之间一对多的依赖关系&#xff0c;当被观察对…

【学习笔记】树上差分总结(点差分/边差分)

一.树上差分的基本概念 1.树上差分的定义 树上差分&#xff0c;顾名思义&#xff0c;意思就是在树上做差分。 至于什么是差分呢&#xff1f;如果不会的同学&#xff0c;可以先看看我的这篇博客:一维,二维差分の详解&#xff08;简单易懂&#xff09;_一维差分-CSDN博客 2.树…

Linux---信号

前言 到饭点了&#xff0c;我点了一份外卖&#xff0c;然后又开了一把网游&#xff0c;这个时候&#xff0c;我在打游戏的过程中&#xff0c;我始终记得外卖小哥会随时给我打电话&#xff0c;通知我我去取外卖&#xff0c;这个时候游戏还没有结束。我在打游戏的过程中需要把外…

CSS写渐变边框线条

box-sizing: border-box; border-top: 1px solid; border-image: linear-gradient(to right, red, blue) 1;

【Java八股文面试系列】JVM-内存区域

目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowError&OOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…

如果通过浏览器调试?

背景&#xff1a;博主是一个有丰富经验的后端开发人员&#xff0c;在前端开发中感觉总是有种力不从心的感觉&#xff0c;因为没有后端debug调试的清晰感。 解决办法&#xff1a;掌握chorm浏览器调试技巧。 F12&#xff0c; F5 打上断点之后&#xff0c;这不就是梦寐之中的调试…

Jenkins升级后,构建任务配置界面重复错位

最近我把公司的Jenkins服务升级到了最新版本&#xff0c;升级完成后&#xff0c;点了一下构建任务&#xff0c;发现能够构建成功&#xff0c;就以为顺利完成升级了&#xff0c;下班走了&#xff0c;结果第二天&#xff0c;进入构建任务配置界面发现&#xff0c;界面一团乱麻&am…

LeetCode 133:克隆图(图的深度优先遍历DFS和广度优先遍历BFS)

回顾 图的Node数据结构 图的数据结构&#xff0c;以下两种都可以&#xff0c;dfs和bfs的板子是不变的。 class Node {public int val;public List<Node> neighbors;public Node() {val 0;neighbors new ArrayList<Node>();}public Node(int _val) {val _val;…

基于springboot地方美食分享网站源码和论文

基于springboot地方美食分享网站源码和论文361 首先&#xff0c;论文一开始便是清楚的论述了系统的研究内容。其次&#xff0c;剖析系统需求分析&#xff0c;弄明白“做什么”&#xff0c;分析包括业务分析和业务流程的分析以及用例分析&#xff0c;更进一步明确系统的需求。然…

基于微信小程序的书籍阅读系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

STM32F407移植OpenHarmony笔记9

继上一篇笔记&#xff0c;已经完成liteos内核的基本功能适配。 今天尝试启动OHOS和XTS兼容性测试。 如何启动OHOS&#xff1f; OHOS系统初始化接口是OHOS_SystemInit(void)&#xff0c;在内核初始化完成后&#xff0c;就能调用。 extern void OHOS_SystemInit(void); OHOS_Sys…

【数据分享】1929-2023年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 之前我们分享过1929-2023年全球气象站点的逐年平均气温数据、逐年最高气温数据…

「优选算法刷题」:计算布尔二叉树的值

一、题目 给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a; 叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。非叶子节点 要么值为 2 要么值为 3 &#xff0c;其中 2 表示逻辑或 OR &#xff0c;3 表示逻辑与 AND…