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

news2024/9/17 7:16:59

文章目录

  • 自己设计用户级缓冲区
    • 简易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 }


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 图(三十八)【第四篇】

接下来&#xff0c;我们先学习一个概念&#xff0c;带有权值的图&#xff0c;其实就是每条边上有一个自己独立的值了&#xff0c;接下来我们来进行一个深入的了解吧。 1.带权值得的图的概念 在前面的课程中&#xff0c;图中的边都只是用来表示两个点之间是否存在关系&#xff…

SQL注入其他方法

此次实验因为环境问题很多无法复现&#xff0c;在此只讨论过程和方法 一、SQL注入之outfile注入 mysql的outfile的作用是导出文件&#xff0c;使用此方法的必要条件&#xff1a;&#xff08;此方法成功率极低&#xff09; 1、知道目标网站的物理路径&#xff1b; 2、%secur…

Python算法题集_螺旋矩阵

Python算法题集_螺旋矩阵 题目54&#xff1a;螺旋矩阵1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【检测4个方向】2) 改进版一【检测2个方向】3) 改进版二【可读性改进】 4. 最优算法 题目54&#xff1a;螺旋矩阵 本文为Python算法题集之一…

《Pandas 简易速速上手小册》第9章:Pandas 数据可视化(2024 最新版)

文章目录 9.1 Pandas 内置可视化工具9.1.1 基础知识9.1.2 重点案例&#xff1a;销售数据分析9.1.3 拓展案例一&#xff1a;产品评价统计9.1.4 拓展案例二&#xff1a;员工满意度分布 9.2 与 Matplotlib 和 Seaborn 集成9.2.1 基础知识9.2.2 重点案例&#xff1a;销售趋势分析9.…

「递归算法」:验证二叉搜索树

一、题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff…

vulhub中Apache APISIX 默认密钥漏洞复现(CVE-2020-13945)

Apache APISIX是一个高性能API网关。在用户未指定管理员Token或使用了默认配置文件的情况下&#xff0c;Apache APISIX将使用默认的管理员Token edd1c9f034335f136f87ad84b625c8f1&#xff0c;攻击者利用这个Token可以访问到管理员接口&#xff0c;进而通过script参数来插入任意…

110.乐理基础-五线谱-五线谱的速度

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;五线谱的附点、休止符、连线、延音线-CSDN博客 上一个内容里练习的答案&#xff1a; 五线谱里的情绪与速度也是跟简谱里一样&#xff0c;详情看&#xff1a;音乐的速度 专栏里的内容&#xff0c;根据创建时间&…

CNN应用Keras Tuner寻找最佳Hidden Layers层数和神经元数量

介绍&#xff1a; Keras Tuner是一种用于优化Keras模型超参数的开源Python库。它允许您通过自动化搜索算法来寻找最佳的超参数组合&#xff0c;以提高模型的性能。Keras Tuner提供了一系列内置的超参数搜索算法&#xff0c;如随机搜索、网格搜索、贝叶斯优化等。它还支持自定义…

《Python 网络爬虫简易速速上手小册》第2章:网络爬虫准备工作(2024 最新版)

文章目录 2.1 选择合适的爬虫工具和库2.1.1 重点基础知识讲解2.1.2 重点案例&#xff1a;使用 Scrapy 抓取电商网站2.1.3 拓展案例 1&#xff1a;使用 Requests 和 BeautifulSoup 抓取博客文章2.1.4 拓展案例 2&#xff1a;使用 Selenium 抓取动态内容 2.2 设置开发环境2.2.1 重…

计算机毕业设计 | vue+SpringBoot图书借阅管理系统(附源码)

1&#xff0c; 概述 1.1 课题背景 随着现在科学技术的进步&#xff0c;人类社会正逐渐走向信息化&#xff0c;图书馆拥有丰富的文献信息资源&#xff0c;是社会系统的重要组成部分&#xff0c;在信息社会中作用越来越重要&#xff0c;在我国图书馆计算机等 信息技术的应用起步…

【Linux】文件重定向与实现支持文件重定向的minishell

目录 0.前提 ​编辑 1.重定向 1.1重定向的本质 1.2dup2 1.3模拟实现输出重定向 > 1.4模拟实现追加重定向 >> 1.5模拟实现输入重定向 < 2.让minishell支持重定向 0.前提 文件描述符的分配规则&#xff1a; 在文件描述符表里面&#xff0c;从小到大按照顺…

linux中的mtime,ctime,atime

目录 结论 文件 touch新文件 调整文件内容 echo直接修改 vi修改 修改文件属性 调整归属 调整权限 读取文件 目录 增加文件 调整目录下文件属性 访问目录下文件 删除文件 结论 mtime&#xff1a;文件内容的修改时间&#xff08;不含权限、属组修改&#xff09; …

计算机网络-封装成帧透明传输(组帧方法)

文章目录 数据链路层功能概述封装成帧透明传输组帧方法字符计数法字符填充法零比特填充法违规编码法 字符填充法为啥复杂和不兼容 数据链路层功能概述 类似老板让小秘书送文件给别的公司&#xff0c;小秘书告诉傻子怎么把该文件送到别的公司的小秘书&#xff0c;然后别的公司的…

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

挑战杯 python 机器视觉 车牌识别 - opencv 深度学习 机器学习

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于python 机器视觉 的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;3分 &#x1f9ff; 更多资…

【王者荣耀】:背后的技术之谜,揭秘游戏背后的实现奥秘!

目录 1、引言 2、游戏引擎 3、网络技术 4、图形渲染 5、操作控制 6、AI算法 7、数据管理 8、安全防护 9、优化与性能 10、未来发展 11、结语 1、引言 随着智能手机的普及和移动互联网的发展&#xff0c;手机游戏已经成为人们日常娱乐的重要组成部分。而在众多手机游…

Oracle Server一台价值百万的服务器内存更换过程

数据库代码敲多了&#xff0c;看乏了吧&#xff01; 带各位DBA看看你们的数据库运行在什么样的硬件上。 1、故障现象 事发时2号位置报警 登录ILO发现内存报警 查看详细信息 查看详细报警 2、关于ORACLE 服务器DIMM 备用 默认情况下在 Oracle ILOM 中启用 DIMM 备用。由 DIMM 提…

MySQL的原生API实现插入数据后在可视化工具上不显示的问题解决

显示表中有两行数据&#xff0c;该表也设置了主键和唯一索引 点进表里看却没有数据 问题原因出现在这里&#xff0c;虽然很多常用的数据库连接池都会开启自动提交&#xff0c;但ibatis的SqlSession使用sessionFactory.openSession()创建时&#xff0c;默认的自动提交是false&am…

vcruntime140.dll最新的修复方法,一键修复vcruntime140.dll的手段

在这篇文章中&#xff0c;我们将深入探讨并详细介绍各种修复vcruntime140.dll文件缺失或损坏问题的方法。鉴于此类问题广泛存在并影响了众多用户&#xff0c;本文目的是向大家展示不同的修复策略&#xff0c;希望能够帮助每个人解决这些棘手的技术难题。下面一起来看看vcruntim…

02-单例模式 ( Singleton Pattern )

单例模式 单例模式设计要点单例模式基础实现摘要实现范例 单例模式的几种实现方式1. 懒汉式&#xff0c;线程不安全2. 懒汉式&#xff0c;线程安全3. 饿汉式4. 双检锁/双重校验锁&#xff08;DCL&#xff0c;即 double-checked locking&#xff09;5. 登记式/静态内部类6. 枚举…