在使用c/c++读取文件,写入文件是很常用的操作,在使用之余很少注意一些细节,比如文件流的缓冲区,系统内核系统空间与用户空间之间的交互操作等,此处来简单描述一下缓冲区
含义:内存中开辟的一片缓冲区域
缓冲类型:全缓冲,行缓冲,不带缓冲
操作方式:
可以通过标准库函数setvbuf来设置缓冲区的类型
setvbuf(_Inout_ FILE * _File, _Inout_updates_opt_z_(_Size) char * _Buf, _In_ int _Mode, _In_ size_t _Size);
参数:
模式 | 描述 |
---|---|
_IOFBF | 全缓冲:对于输出,数据在缓冲填满时被一次性写入。对于输入,缓冲会在请求输入且缓冲为空时被填充。 |
_IOLBF | 行缓冲:对于输出,数据在遇到换行符或者在缓冲填满时被写入,具体视情况而定。对于输入,缓冲会在请求输入且缓冲为空时被填充,直到遇到下一个换行符。 |
_IONBF | 无缓冲:不使用缓冲。每个 I/O 操作都被即时写入。buffer 和 size 参数被忽略。 |
返回值
如果成功,则该函数返回 0,否则返回非零值。
这里要简单说一下,我为什么会用到文件缓冲区以及,修改缓冲区的值,来满足自己的开发需求。
我在使用 FILE 读写文件时,打开了一个较大的文件大概50K左右的文本本件,如下:
FILE *fpOut=fopen(fileDir.c_str(),"w");
正常读写是没什么问题的,然而,在读取了该文件之后,我想要在内存中直接获取到读到的内容(转存为字符串),出于这种想法,我查看了 fpOut的成员 fpOut->_base与fpOut->_ptr,该内存区域存储的就是读入的文件内容,我就想着直接将该部分内容取出来使用,结果也是可以的,只限于小文件,可以正常使用(仅限于小文件大小小于fpOut->_bufsiz值4096,即一个页的大小,这个大小是默认的),当文件大于该缓冲区(fpOut->_bufsiz 4096),则直接从该内存处拿取的内容就不完整了,因为这个是临时缓冲区,当读入的内容满了之后就会清除,然后再读入新的内容,这样子就不能直接使用了,要想直接获取全部的内容则可以手动更改该缓冲区的大小,这就用到了上面的函数setvbuf(),缓冲区的模式,来提高读写效率(根据实际情况设置较大的缓冲区,减少调用内核操作),具体的操作可以测试每种模式的不同之处
#define FILE_BUFF_SIZE 102400 char buf[FILE_BUFF_SIZE]; setvbuf(fpOut,buf,_IOFBF,FILE_BUFF_SIZE);
函数fflush与setbuf函数的使用
关于setvbuf()函数的详解_化茧成蝶007-CSDN博客