浅入缓冲区
浅入缓冲区
对应在内存中预留的一段空间;用来缓冲输入或者输出的数据;也就是对应的输入缓冲区和输出缓冲区。
那么为什么要引入缓冲区:
每一次对文件进行的读写操作都需要执⾏⼀次系统调 ⽤,执⾏⼀次系统调⽤将涉及到CPU状态的切换,即从⽤⼾空间切换到内核空间,实现进程上下⽂的 切换,这将损耗⼀定的CPU时间,频繁的磁盘访问对程序的执⾏效率造成很⼤的影响。
如果加上了缓冲区,那么就减少磁盘的读写次数, 再加上计算机对缓冲区的操作⼤ 快于对磁盘的操作,故应⽤缓冲区可⼤ 提⾼计算机的运⾏速度。
什么时候刷新:
1.用户强制刷新(fflush后)。 2·满足刷新条件(也就是后面三种缓冲区对应满足的条件)。 .进程退出。
三种缓冲区类型:
①全缓冲区:当都写满了后;自动刷新到,之后调用系统的IO操作;如磁盘上普通文件的操作。 ②行缓冲区:遇到换行符进行刷新;也就是对应的终端操作:显示器输入输出等就是行刷新;默认⾏缓冲区的⼤⼩为1024。 ③无缓冲区:标准I/O库不对字符进⾏缓存,直接调⽤系统调⽤,如标准出错流stderr通 常是不带缓冲区的,这使得出错信息能够尽快地显⽰出来。
下面由一张图展示IO库和和系统之间进行文件操作的关系:
c语言的一个文件指针类型;其实是一个结构体;它封装了系统调用需要的fd;以及里面还封装了一个自己的缓冲区。
大致结构:
后面我们会模拟实现一个简单的版本。
下面展示一段代码:
第一次执行(直接运行):
第二次执行:
下面我们简单的围绕缓冲区这个概念;利用我们上面所设计的知识简单实现一个模拟c库封装的用户级别的文件操作:
模拟实现相关接口函数:mfopen,mfclose,mfflush,mfwrite。 涉及知识:缓冲区,FILE结构体,语言层封装的系统层IO操作。 采用语言:c语言。
我们所谓的FILE其实就是typedef出来的:
这里可以理解为,每次我们利用语言层封装的fopen打开的一个文件类型不就是FILE*;也就是创造了一个这个类型结构体对象。
下面我们来实现上面所说的函数:
mystio.h:
代码语言:javascript代码运行次数:0运行复制#pragma once
#define SIZE 1024
#define FLUSH_OE 0
#define FLUSH_LIE 1
#define FLUSH_FULL 2
struct IO_FILE
{
int fla; //文件访问方式
int fileno; //文件描述符
char outbuffer[SIZE];//缓冲区
int cap;//最大容量
int size;//当前尺寸
int flus;//刷新方式
};
typedef struct IO_FILE mFILE;
struct IO_FILE*mfopen(ct char *filename, ct char *mode);
int mfwrite(ct void *ptr, int num, mFILE *stream);
void mfflush(mFILE *stream);
void mfclose(mFILE *stream);
:
代码语言:javascript代码运行次数:0运行复制#include"mystio.h"
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
mFILE* buyf(int fileno,int flag){
mFILE*f=(mFILE*)malloc(sizeof(mFILE));
if(f == ULL) return ULL;
f->fla=flag;
f->fileno=fileno;
f->flus=FLUSH_LIE;//默认设置成行刷新
f->cap=SIZE;
f->size=0;
memset(f->outbuffer,0,sizeof(f->outbuffer));
return f;
}
mFILE *mfopen(ct char *filename,ct char *mode){
umask(0);
int fd=-1;
int flag=0;
if(strcmp(mode,"r")==0){
flag = O_RDWR;
fd = open(filename, flag);
}
else if(strcmp(mode,"w")==0){
flag = O_CREAT | O_WROLY | O_TRUC;
fd = open(filename, flag, 0666);
}
else if(strcmp(mode, "a") == 0)
{
flag = O_CREAT | O_WROLY | O_APPED;
fd = open(filename, flag, 0666);
}
else{}
if(fd < 0) return ULL;
return buyf(fd, flag);
}
int mfwrite(ct void *ptr, int num, mFILE *stream){
//依靠size每次判断好要写入的位置,要么直接写在后面要么遇到换行符,直接刷新出去
//这里清空操作直接用覆盖来代替(也就是把size改成0)
memcpy(stream->outbuffer+stream->size,ptr,num);
stream->size+=num;
if(stream->size>0&&stream->flus== FLUSH_LIE&&stream->outbuffer[stream->size-1]=='\n' )
{
mfflush(stream);
}
return num;
}
void mfflush(mFILE *stream){
if(stream->size>0){
write(stream->fileno,stream->outbuffer,stream->size);//写入内核缓冲区
fsync(stream->fileno);//把内核缓冲区写入磁盘
stream->size=0;
}
}
void mfclose(mFILE *stream){
if(stream->size>0){//关闭前,先看是否用户级缓冲区有数据,先写入内核缓冲区再清空
mfflush(stream);
stream->size=0;
}
close(stream->fileno);
}
:
代码语言:javascript代码运行次数:0运行复制#include<stdio.h>
#include"mystio.h"
#include <string.h>
#include <unistd.h>
int main()
{
mFILE *fp = mfopen("", "a");
if(fp == ULL)
{
return 1;
}
int cnt = 5;
while(cnt)
{
printf("write %d\n", cnt);
char buffer[64];
snprintf(buffer, sizeof(buffer),"hello message, number is : %d\n", cnt);
cnt--;
mfwrite(buffer, strlen(buffer), fp);
//mfflush(fp);
sleep(1);
}
mfclose(fp);
free(stream);
}
下面我们来测试一下:
测试一(每次mfwrite写入的时候以\n结尾,也就是让它实现行刷新):
测试二(每次写入的时候故意不输入\n,而是手动刷新):
测试三(把手动刷新去掉,让它直接都写入缓冲区;最后等到mfclose关闭后自己检查缓冲区是否存在数据完成刷新):
今天的缓冲区小知识到此为止;希望对大家的对此认识能更加清晰,万分感谢!!!
在这篇文章的结尾,我满心感激。感谢您愿意耐心地读完我的文字,您的阅读如同阳光照亮了我创作的道路,愿我们在文字的世界里继续相伴前行,共享更多的美好与感动。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-12-17,如有侵权请联系 cloudcommunity@tencent 删除stream测试磁盘内核系统#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上一篇:探究解数独问题
下一篇:Linux命令行解释器的模拟实现
推荐阅读
留言与评论(共有 14 条评论) |
本站网友 广东爱情故事 | 29分钟前 发表 |
先写入内核缓冲区再清空 mfflush(stream); stream->size=0; } close(stream->fileno); } | |
本站网友 麦轮胎 | 6分钟前 发表 |
"r")==0){ flag = O_RDWR; fd = open(filename | |
本站网友 v是几 | 17分钟前 发表 |
我们所谓的FILE其实就是typedef出来的:95ab41c94094b0eadba2b566d7d8948.png这里可以理解为 | |
本站网友 v社 | 28分钟前 发表 |
下面我们来实现上面所说的函数: mystio.h | |
本站网友 黄山市人民医院 | 11分钟前 发表 |
涉及知识:缓冲区 | |
本站网友 钢架结构房子 | 16分钟前 发表 |
mfclose | |
本站网友 车前草功效 | 25分钟前 发表 |
我们所谓的FILE其实就是typedef出来的:95ab41c94094b0eadba2b566d7d8948.png这里可以理解为 | |
本站网友 馅饼里包了一块天 | 26分钟前 发表 |
cnt); cnt--; mfwrite(buffer | |
本站网友 新电脑如何分区 | 30分钟前 发表 |
ptr | |
本站网友 关于两会 | 1秒前 发表 |
这将损耗⼀定的CPU时间 | |
本站网友 市桥 | 16分钟前 发表 |
如有侵权请联系 cloudcommunity@tencent 删除前往查看stream测试磁盘内核系统 | |
本站网友 范曾的画 | 24分钟前 发表 |
本文参与 腾讯云自媒体同步曝光计划 | |
本站网友 手机gps定位 | 1分钟前 发表 |
mfwrite |