当前位置: 首页 > news >正文

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

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

      • 刷新缓冲逻辑图
      • 自定义实现
      • 如何强制刷新内核缓冲区
      • 例子

刷新缓冲逻辑图

在这里插入图片描述

自定义实现

mystdio.h
#pragma once 
#include <stdio.h>#define NUM 1024
#define BUFF_NOME 0x1
#define BUFF_LINE 0x2
#define BUFF_ALL 0x4typedef 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);//将用户缓冲区的数据,通过系统调用接口,冲刷给oswrite(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;
}

在这里插入图片描述

例子

像我们进行scanf输入的时候,其实本身我们输入的是一串字符串,将这个字符串读入对应的缓冲区buff后,然后通过分解工作,进一步传入系统,系统,系统在通过一些指令输入输出想要的结果

相关文章:

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

模拟实现FILE以及认识缓冲区 刷新缓冲逻辑图自定义实现如何强制刷新内核缓冲区例子 刷新缓冲逻辑图 自定义实现 mystdio.h #pragma once #include <stdio.h>#define NUM 1024 #define BUFF_NOME 0x1 #define BUFF_LINE 0x2 #define BUFF_ALL 0x4typedef struct _MY_FIL…...

【Terraform学习】使用 Terraform 将 EC2 实例作为 Web 服务器启动(Terraform-AWS最佳实战学习)

使用 Terraform 将 EC2 实例作为 Web 服务器启动 实验步骤 前提条件 安装 Terraform&#xff1a; 地址 下载仓库代码模版 本实验代码位于 task_ec2 文件夹中。 变量文件 variables.tf 在上面的代码中&#xff0c;您将声明&#xff0c;aws_access_key&#xff0c;aws_secr…...

WebGL 变量uniform、gl.getUniformLocation、gl.uniform4f及其同族函数相关

目录 uniform变量命名规范 获取 uniform 变量的存储地址 gl.getUniformLocation 向uniform变量赋值 gl.uniform4f ​编辑 gl.uniform4f()的同族函数 demo&#xff1a;点击webgl坐标系的四个象限绘制各自不同颜色的点 uniform变量命名规范 var FSHADER_SOURCE uniform vec4…...

【Visual Studio】生成.i文件

环境 VS版本&#xff1a;VS2013 问题 如何生成.i预编译文件&#xff1f; 步骤 1、打开VS项目属性&#xff0c;打开C/C\预处理器页面&#xff0c;【预处理到文件】选择是&#xff0c;开启。 2、生成文件如下。 3、正常编译需要关闭此选项。...

本地生活服务平台加盟哪家公司好?

本地生活的竞争从年初的火热到现在&#xff0c;已经进入了下半场&#xff0c;随着优胜劣汰的筛选&#xff0c;那么直到现在&#xff0c;想做本地生活服务平台加盟&#xff0c;哪家公司比较好呢&#xff0c;应该如何选择呢&#xff1f; 首先我们得弄懂&#xff0c;我们加盟本地…...

css-grid使用

文章目录 grid概念容器和项目网格轨道&#xff1a;网格单元网格线 使用分配item空间大小对于子元素的意义 行列指定隐式和显示网格默认排列 grid容器属性grid-template-rows: 100px 100px 200px;grid-template-columns: 100px 100px 100px;grid-auto-rows: 200pxgrid-column-ga…...

springBoot提取一个List<?>中的某个字段集合

import cn.hutool.core.collection.CollUtil;PageResult prrecommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId);List<RecommendUser> items (List<RecommendUser>) pr.getItems(); //提取所有推荐的用户id List<Long> ids …...

【BUG】 ‘cv2.cv2‘ ‘wechat_qrcode_WeChatQRCode‘

首发博客地址 https://blog.zysicyj.top/ 报错内容 AttributeError: module cv2 has no attribute wechat_qrcode_WeChatQRCode 解决方法 pip install opencv-pythonpip install opencv-contrib-python 本文由 mdnice 多平台发布...

10 Mybatis

文章目录 1 概述1.1 什么是Mybatis?1.2 JDBC介绍(了解)1.2.1 问题分析1.2.2 技术对比 1.3 数据库连接池1.4 lombok 2 Mybatis基础操作2.1 准备2.2 删除2.2.1 日志输入2.2.2 预编译SQL2.2.2.1 介绍2.2.2.2 SQL注入2.2.2.3 参数占位符 2.3 新增2.3.1 主键返回 2.4 更新2.5 查询2…...

【PHP】PHP的面向对象编程

PHP面向对象编程是PHP编程的一个重要方向&#xff0c;它通过将数据和操作封装在对象中&#xff0c;使得代码更加模块化、可重用性和易于维护。本文将介绍PHP面向对象编程的基本概念、核心思想和常见应用&#xff0c;并探讨使用PHP面向对象编程时需要注意的问题。 一、概述 PH…...

Windows10突然出现音频无法正常运行的解决方法

文章目录 前言 一 问题描述 二 解决方法 2.1 下载完成之后选择安装 2.2 选择其他位置来安装 2.3 静静等待安装完成 三 升级Windows显卡和声卡 总结 前言 本文主要介绍Windows里面的音频出现问题的解决方法 一 问题描述 Windows使用好好的&#xff0c;突然就出现声卡出…...

Maven面试题大全及答案

1.什么是Maven&#xff1f; Maven使用项目对象模型(POM)的概念&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的软件项目管理工具。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可…...

探究字符串匹配算法:暴力法与KMP算法的Java实现

探究字符串匹配算法&#xff1a;暴力法与KMP算法的Java实现 字符串匹配是计算机科学中的基本问题之一&#xff0c;它涉及在一个主串中查找特定的子串。在本文中&#xff0c;我们将深入探讨暴力法和KMP算法这两种常见的字符串匹配算法&#xff0c;并提供详细的Java代码示例。 …...

前端面试:【浏览器与渲染引擎】工作原理与渲染流程

嗨&#xff0c;亲爱的读者&#xff01;你是否曾经好奇过当你在浏览器中输入URL并按下回车时&#xff0c;网页是如何显示在你的屏幕上的&#xff1f;这背后涉及了复杂的浏览器工作原理和渲染流程。本文将带你深入了解浏览器如何工作以及网页如何被渲染出来。 1. 浏览器的工作原理…...

PySide6学习笔记--gui小模版使用

一、界面绘制 1.desiner画图 2.画图代码 # -*- coding: utf-8 -*-################################################################################ ## Form generated from reading UI file t1gui.ui ## ## Created by: Qt User Interface Compiler version 6.5.2 ## ##…...

如何用Python实现冒泡排序

1 问题 冒泡排序是一种简单的排序算法&#xff0c;它也是一种稳定排序算法。其实现原理是重复扫描待排序序列&#xff0c;并比较每一对相邻的元素&#xff0c;当该对元素顺序不正确时进行交换。一直重复这个过程&#xff0c;直到没有任何两个相邻的元素可以交换&#xff0c;就表…...

C++Qt堆叠窗体的使用案例

本博文源于笔者最近学习的Qt&#xff0c;内容讲解堆叠窗体QStackedWidget案例&#xff0c;效果是选择左侧列表框中不同的选项时&#xff0c;右侧显示所选的不同的窗体。 案例效果 案例书写过程 控件都是动态创建的&#xff0c;因此.h文件需要创建控件&#xff0c;.cpp书写业务…...

Linux之套接字UDP实现网络通信

Linux之套接字UDP实现网络通信 文章目录 Linux之套接字UDP实现网络通信1.引言2.具体实现2.1需要知道的套接字接口1.socket()2.bind()3.recvfrom()4.sendto() 2.2服务器端server.hpp2.3服务器端server.cc2.4客户端Client.cc 1.引言 ​ 套接字(Socket)是计算机网络中实现网络通信…...

Matlab绘制二值图像

二值化介绍 只有黑白两种颜色的图像称为黑白图像或单色图像&#xff0c;是指图像的每个像素只能是黑或者白&#xff0c;没有中间的过渡&#xff0c;故又称为二值图像。其特点是二值图像的像素值只能为0和1&#xff0c;分别代表黑色和白色&#xff0c;图像中的每个像素值用1位存…...

Kali 网络参数的配置

手工方式 Wired 有线 Woreless 无线 图形化的网络管理器&#xff08;依赖的服务&#xff1a;NetworkManager&#xff09; ┌──(root㉿kali)-[~] └─# systemctl status NetworkManager ● NetworkManager.service - Network ManagerLoaded: loaded (/lib/systemd/system/N…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...