【LeetCode】模拟实现FILE以及认识缓冲区

这篇具有很好参考价值的文章主要介绍了【LeetCode】模拟实现FILE以及认识缓冲区。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

刷新缓冲逻辑图

【LeetCode】模拟实现FILE以及认识缓冲区,Linux,leetcode,linux,算法

自定义实现

mystdio.h
#pragma once 
#include <stdio.h>

#define NUM 1024
#define BUFF_NOME 0x1
#define BUFF_LINE 0x2
#define BUFF_ALL 0x4

typedef struct _MY_FILE
{
  int fd;//接受描述符的值
  int flags;//用来记录打开方式
  char outputbuffer[NUM];//缓冲区保存
  int current;//记录缓冲区有多少字符
}MY_FILE;

MY_FILE* my_fopen(const char* path,const char* mode);
size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* stream);
int my_fclose(MY_FILE* fp);
int my_fflush(MY_FILE* fp);
mystdio.c
#include "mystdio.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

MY_FILE* my_fopen(const char* path,const char* mode)
{
  //1.识别标志位,打开方式
  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 if(strcmp(mode,"r+") == 0) flag |= (O_WRONLY | O_RDONLY);
  else if(strcmp(mode,"w+") == 0) flag |= (O_CREAT | O_WRONLY | O_RDONLY | O_TRUNC);
  else if(strcmp(mode,"a+") == 0) flag |=(O_CREAT | O_WRONLY | O_RDONLY | O_APPEND);
  //2.尝试打开文件
  mode_t m = 0666;
  int fd = 0;
  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;
  mf->flags = 0;
  mf->flags |= BUFF_LINE;
  memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer));
  mf->current = 0;

  //5.返回打开的文件
  return mf;
}

//冲刷缓冲区
int my_fflush(MY_FILE* fp)
{
  assert(fp);
  //将用户缓冲区的数据,通过系统调用接口,冲刷给os
  write(fp->fd,fp->outputbuffer,fp->current);
  fp ->current = 0;

  //fsync(fp-fd);
  return 0;
}

//这里返回的是字节数,不是模拟实现的输入的、个数nmemb
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;

  size_t write = 0;
  if(my_size >= user_size) 
  {
    memcpy(stream->outputbuffer + stream->current,ptr,user_size);
   //3.更新计数器字段
    stream->current += user_size;
    write = user_size;
  }
  else 
  {
    //如果缓冲区内存不够存放的话,指挥存放它的最大值
    memcpy(stream->outputbuffer+stream->current,ptr,my_size);
    stream->current += my_size;
    write = 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 write;
}


int my_fclose(MY_FILE* fp)
{
  assert(fp);
  //1.冲刷缓冲区
  if(fp->current > 0) my_fflush(fp);

  //2.关闭文件
  close(fp->fd);

  //3.释放堆空间
  free(fp);

  //4.指针置NULL --- 可以设置
  fp = NULL;

  return 0;
}
main.c
#include "mystdio.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define MYFILE "log.text"
int main()
{
  MY_FILE* fp = my_fopen(MYFILE,"w");
  if(fp == NULL) return 1;

  const char* str = "hello my my_fwrite";
  int cnt = 10;
  //操作文件
  while(cnt)
  {
    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;
}

如何强制刷新内核缓冲区

根据文件描述符进行强制刷新

main.c
#include "mystdio.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define MYFILE "log.text"
int main()
{
  MY_FILE* fp = my_fopen(MYFILE,"w");
  if(fp == NULL) return 1;

  const char* str = "hello my my_fwrite";
  int cnt = 10;
  //操作文件
  while(cnt)
  {
    char buffer[1024];
    snprintf(buffer,sizeof(buffer),"%s:%d\n",str,cnt--);
    if(cnt % 5 == 0)
    {
    	//当cnt是五的倍数的时候就会强制刷新一次
    	my_fwrite(buffer,strlen(buffer),1,fp);
    }
  }
    my_fclose(fp);

    return 0;
}

【LeetCode】模拟实现FILE以及认识缓冲区,Linux,leetcode,linux,算法

例子

像我们进行scanf输入的时候,其实本身我们输入的是一串字符串,将这个字符串读入对应的缓冲区buff后,然后通过分解工作,进一步传入系统,系统,系统在通过一些指令输入输出想要的结果文章来源地址https://www.toymoban.com/news/detail-671833.html

到了这里,关于【LeetCode】模拟实现FILE以及认识缓冲区的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【linux深入剖析】文件描述符 | 对比 fd 和 FILE | 缓冲区

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 通过对open函数的学习,我们知道了文件描述符就是一个小整数 而现在知道,文件描述符就是从0开始的小

    2024年04月13日
    浏览(48)
  • (9)Linux Git的介绍以及缓冲区

    💭 前言 本章我们先对缓冲区的概念进行一个详细的探究,之后会带着大家一步步去编写一个简陋的 \\\"进度条\\\" 小程序。最后我们来介绍一下 Git,着重讲解一下 Git 三板斧,一般只要掌握三板斧就基本够用了。 先说一下 unistd.h 库中的 sleep 函数,它可以按照秒去休眠 我们先创

    2024年02月03日
    浏览(51)
  • 【linux基础I/O(二)】文件系统讲解以及文件缓冲区的概念

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Linux从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学更多操作系统知识   🔝🔝 对于文件来讲,有打开的在内存中 的文件,也有没有打开的在磁盘上 文件,上一篇文章讲解的是前者,本篇 文章将带大家了解后

    2024年01月19日
    浏览(56)
  • 环形缓冲区 Ring Buffer 的实现

    环形缓冲区(Circular Buffer 或 Ring Buffer)是一种数据结构,它在逻辑上形成一个闭环。这种结构非常适用于需要固定大小的缓冲区的情况,如音频处理、网络通信、实时数据传输等。环形缓冲区的主要特点和用途包括: 固定大小:环形缓冲区的大小在创建时确定,并且在其生

    2024年02月05日
    浏览(49)
  • 使用环形缓冲区ringbuffer实现串口数据接收

    环形缓冲区(ringbuffer),实际上就是一种队列数据结构,只不过它不是线性队列,而是环形队列。 关于环形缓冲区(ringbuffer)的详细介绍,网上一搜一大把,这里不重复介绍了,我这里直接上代码。 详细介绍可以参考下面链接里面的介绍: https://en.wikipedia.org/wiki/Circular_b

    2023年04月19日
    浏览(43)
  • C++文件操作基础 读写文本、二进制文件 输入输出流 文件位置指针以及随机存取 文件缓冲区以及流状态

    文本文件一般以行的形式组织数据。 包含头文件: #include fstream 类: ofstream(output file stream) ofstream 打开文件的模式(方式):类内open()成员函数参数2.参数1是文件存储/创建路径 例如:fout.open(filename,ios::app); 对于 ofstream,不管用哪种模式打开文件,如果文件不存在,都会创

    2024年01月25日
    浏览(52)
  • linuxC语言缓冲区及小程序的实现

    为缓和 CPU 与 I/O 设备之间速度不匹配,文件缓冲区用以暂时存放读写期间的文件数据而在内存区预留的一定空间。使用文件缓冲区可减少读取硬盘的次数。 系统自动地在内存为程序中每一个正在使用的文件开辟一块文件缓冲区。 从内存向磁盘输出数据,先送到内存中的缓冲

    2024年02月04日
    浏览(40)
  • C++环形缓冲区设计与实现:从原理到应用的全方位解析

    环形缓冲区(Circular Buffer),也被称为循环缓冲区(Cyclic Buffer)或者环形队列(Ring Buffer),是一种数据结构类型,它在内存中形成一个环形的存储空间。环形缓冲区的特点是其终点和起点是相连的,形成一个环状结构。这种数据结构在处理流数据和实现数据缓存等场景中具

    2024年02月07日
    浏览(61)
  • 【看表情包学Linux】缓冲区的概念 | Git 三板斧 | 实现简易进度条

       爆笑教程,只送有缘人  👉 《看表情包学Linux》 💭 写在前面: 本章我们先对缓冲区的概念进行一个详细的探究,之后会带着大家一步步去编写一个简陋的 \\\"进度条\\\" 小程序,过程还是挺有意思的,虽然实现的过程表现得非常沙雕,但它是本 Linux 专栏中第一个小程序。

    2024年02月02日
    浏览(50)
  • Java中使用JTS实现WKT字符串读取转换线、查找LineString的list中距离最近的线、LineString做缓冲区扩展并计算点在缓冲区内的方位角

    Java中使用JTS对空间几何计算(读取WKT、距离、点在面内、长度、面积、相交等): Java中使用JTS对空间几何计算(读取WKT、距离、点在面内、长度、面积、相交等)_jts-core_霸道流氓气质的博客-CSDN博客 Java+GeoTools实现WKT数据根据EPSG编码进行坐标系转换: Java+GeoTools实现WKT数据根据

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包