stdio的缓冲区
来源:互联网 发布:数控仿真模拟软件 编辑:程序博客网 时间:2024/06/06 19:11
为什么要有缓冲区(Buffer)
原因为多种,有两个重点:
1. 从内存中读取数据比从文件中读取数据要快得多(这只是一种浅显地说法,但确实能说明问题)。
2. 对文件的读写需要用到open、read、write等系统底层函数,而用户进程每调用一次系统函数都要从用户态切换到系统态,等执行完毕后再返回用户态,这种切换要花费一定时间成本(对于高并发程序而言,这种状态的切换会影响到程序性能)。
举个例子,如果程序需要处理10K个整数(或者10K个字符串等等),而这些整数事先存在某个文件中,如果程序每处理一个整数就要从文件中读一个整数(read系统调用),那么每次都要进行硬件I/O、进程状态切换等操作,这样效率是非常低下的。如果每次从文件中读出1K个整数到内存,程序从内存中读取数据并处理,那么程序的性能会明显提高,存储这1K个整数的内存区域就是一个缓冲区。
由于目前计算机体系结构的限制,有时必须采用某些低效的手段。利用低效的手段一次性读出适量的数据到内存,以后的各种操作就只针对内存中的数据展开,从而实现对低效手段的缓冲,提高效率,这种机制称为缓冲机制,而内存中存储数据的区域就称为缓冲区。
stdio库(libc库的一部分)中的函数已经对文件实现了缓冲机制,并高度优化,可以直接应用到很多项目中。
Stdio的缓冲机制
fread函数
fread函数的缓冲机制中有如下几个重要的变量:
1. pBase:指向缓冲区的指针
2. nBufSize:缓冲区长度
3. pToRead:指向缓冲区中未读取数据的指针
4. nByteLeft:缓冲区中未读取数据字节数
如图所示,红色区域表示已经读入数据的缓冲区,灰色表示空闲的缓冲区。默认缓冲区一般为4096字节(缓冲区可以由用户指定,详见后文),当然,这个长度可以根据文件长度灵活地变化。
即使用户读取了一个字节的数据,fread也会事先从文件中读取缓冲区大小的数据来填充缓冲区,当然,如果文件长度小于缓冲区大小,那么文件的全部内容都会被读入缓冲区。
当缓冲区有了数据,fread就可以从缓冲区中读取数据了。设nCount是要读入的数据长度,nFileSize是文件的长度,在初始状态下(即在第一次执行fread函数时),pToRead= pBase,nByteLeft = FileSize > nBufSize?nFileSize:nBufSize。
如果nCount小于nByteLeft,那么每次从缓冲区的pToRead位置拷贝nCount个字节到用户定义的空间中去(即fread的第一个参数指向的空间),拷贝之后将pToRead向后移动nCount个字节,并将nByteLeft减少nCount,当nByteLeft为零时,fread将重新调用系统函数读取文件来刷新缓冲区(各参数又回到了一开始的状态)。
如果nCount大于nByteLeft,需要分多次才能将数据拷贝到用户定义的空间中,先从缓冲区中读取nByteLeft个字节,并刷新缓冲区,再读取剩下的字节,显然这样的开销更大。这里需要注意的是,当一次读入的数据长度超过缓冲区大小时(如大于4K),fread函数将不再采用缓冲机制。所以用fread读数据时,如何确定数据的长度应该三思而行。
上面只是fread函数缓冲机制的一个笼统的介绍,而具体的机制是怎么样的呢?聪明的读者可以自己试着实现一下。
fwrite函数
与缓冲相关的库函数
Stdio的安全问题
并发读写文件引起的数据正确性问题。
- stdio的缓冲区
- fork(2), stdio 行/块缓冲区,子进程为何输出fork()之前的东西
- #include<stdio>与#include"stdio"的区别
- stdio.h的说明
- android stdio的快捷键
- stdio 的 buffer 问题
- android stdio 的github
- stdio
- STDIN_FILENO与stdio的区别
- Visual Stdio 2008 的卸载
- stdio.h常用的函数
- android stdio 常用的快捷键
- android stdio出现的 问题
- uart stdio的移植1
- uart stdio的移植2
- uart stdio的移植3
- 13.2 stdio库的缓冲
- Android stdio的彻底删除
- 最短路径问题
- 单例模式
- 第二章 仿Windows计算器
- 梁定郊在英十几年,旅行贿赠福利
- 图解Linux命令之--date命令
- stdio的缓冲区
- www-authenticate
- CentOS下开启mysql远程连接
- 获取内置sd卡和外置sd卡的方法!经三星pad SM T585c型号测试有效。
- 智能电源管理技术--原理简介
- 从源码分析View绘制流程
- 关于android有用的干货知识点
- 并发并行同步异步多线程的区别
- 图结构练习——最短路径