刷新緩沖邏輯圖
自定義實(shí)現(xiàn)
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;//用來(lái)記錄打開(kāi)方式
char outputbuffer[NUM];//緩沖區(qū)保存
int current;//記錄緩沖區(qū)有多少字符
}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.識(shí)別標(biāo)志位,打開(kāi)方式
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.嘗試打開(kāi)文件
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對(duì)象,需要先進(jìn)行構(gòu)建
MY_FILE *mf = (MY_FILE*)malloc(sizeof(MY_FILE));
if(mf == NULL)
{
close(fd);
return NULL;
}
//4.初始化MY_FILE對(duì)象
mf->fd = fd;
mf->flags = 0;
mf->flags |= BUFF_LINE;
memset(mf->outputbuffer,'\0',sizeof(mf->outputbuffer));
mf->current = 0;
//5.返回打開(kāi)的文件
return mf;
}
//沖刷緩沖區(qū)
int my_fflush(MY_FILE* fp)
{
assert(fp);
//將用戶緩沖區(qū)的數(shù)據(jù),通過(guò)系統(tǒng)調(diào)用接口,沖刷給os
write(fp->fd,fp->outputbuffer,fp->current);
fp ->current = 0;
//fsync(fp-fd);
return 0;
}
//這里返回的是字節(jié)數(shù),不是模擬實(shí)現(xiàn)的輸入的、個(gè)數(shù)nmemb
size_t my_fwrite(const void* ptr,size_t size,size_t nmemb,MY_FILE* stream)
{
//1、緩沖區(qū)如果已經(jīng)滿了,就直接寫(xiě)入
if(stream->current == NUM)my_fflush(stream);
//2.根據(jù)緩沖區(qū)剩余情況,進(jìn)行數(shù)據(jù)拷貝即可
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.更新計(jì)數(shù)器字段
stream->current += user_size;
write = user_size;
}
else
{
//如果緩沖區(qū)內(nèi)存不夠存放的話,指揮存放它的最大值
memcpy(stream->outputbuffer+stream->current,ptr,my_size);
stream->current += my_size;
write = my_size;
}
//4.開(kāi)始計(jì)劃刷新,他們高效體現(xiàn)在哪里? --- TODO
//不發(fā)生刷新的本質(zhì),不進(jìn)行寫(xiě)入,就是不進(jìn)行IO,不進(jìn)行調(diào)用系統(tǒng)調(diào)用,所以my_fwrite函數(shù)調(diào)用會(huì)非??欤瑪?shù)據(jù)會(huì)暫時(shí)保存在緩沖區(qū)中
//可以在緩沖區(qū)中擠壓多份數(shù)據(jù),統(tǒng)一進(jìn)行刷新寫(xiě)入,本質(zhì):就是一次IO可以IO更多的數(shù)據(jù),提高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.沖刷緩沖區(qū)
if(fp->current > 0) my_fflush(fp);
//2.關(guān)閉文件
close(fp->fd);
//3.釋放堆空間
free(fp);
//4.指針置NULL --- 可以設(shè)置
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("當(dāng)前成功寫(xiě)入:%lu個(gè)字節(jié)\n",size);
}
my_fclose(fp);
return 0;
}
如何強(qiáng)制刷新內(nèi)核緩沖區(qū)
根據(jù)文件描述符進(jìn)行強(qiáng)制刷新
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)
{
//當(dāng)cnt是五的倍數(shù)的時(shí)候就會(huì)強(qiáng)制刷新一次
my_fwrite(buffer,strlen(buffer),1,fp);
}
}
my_fclose(fp);
return 0;
}
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-685318.html
例子
像我們進(jìn)行scanf輸入的時(shí)候,其實(shí)本身我們輸入的是一串字符串,將這個(gè)字符串讀入對(duì)應(yīng)的緩沖區(qū)buff后,然后通過(guò)分解工作,進(jìn)一步傳入系統(tǒng),系統(tǒng),系統(tǒng)在通過(guò)一些指令輸入輸出想要的結(jié)果文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-685318.html
到了這里,關(guān)于【Linux】模擬實(shí)現(xiàn)FILE以及認(rèn)識(shí)緩沖區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!