标准 IO 库的缓冲区
标准 IO 库的缓冲区
首先需要明确一点: 标准 IO 库提供缓冲区的目的是尽可能减少系统调用 read 和 write 函数的调用次数. 之后会给出例子直观的显示缓冲区的大小对程序性能的影响.
标准 IO 提供了 3 种类型的缓冲:
- 全缓冲: 其特点是需要填满缓冲区后才进行实际的 IO 操作(当然, 也可以使用
flush
对缓冲区进行冲洗), 一般对于磁盘上的文件实施的是全缓冲. 默认全缓冲的大小为 4096; - 行缓冲: 当输入输出遇到换行符时, 才执行 IO 操作. 当流涉及一个终端时, 通常使用行缓冲. 行缓冲的长度是固定的, 稍微小一些, 默认是 1024;
- 不带缓冲: 标准 IO 库不对字符进行缓冲. 比如标准错误输出 stderr 通常是不带缓冲的, 这样即使没有换行符, 出错信息也能尽快显示. 此时缓冲的大小为 1.
测试缓冲大小对程序性能的影响
下面给出一个例子展示缓冲区的大小对程序性能的影响, 该程序实现对文件的读, 然后将内容显示到屏幕上. 根据上面介绍的内容, 使用标准 IO 库对磁盘上的文件进行处理时, 实施的全缓冲. 之后, 我们将缓冲类型设置为不带缓冲, 从而比较两种类型的缓冲对程序性能的影响.
/* test_buffer.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>#define oops(msg) {perror(msg); exit(1);}int main() {char buf[100];FILE *fp;if ((fp = fopen("file", "r")) == NULL)oops("fopen");/*setbuf(fp, NULL);*/struct timeval t_val, t_val_end, t_result;gettimeofday(&t_val, NULL);while (fgets(buf, 100, fp) != NULL)printf("%s", buf);gettimeofday(&t_val_end, NULL);timersub(&t_val_end, &t_val, &t_result);double consume = t_result.tv_sec + (1.0 * t_result.tv_usec)/1000000;printf("end.elapsed time= %fs \n", consume);
}
其中文件 file 有 20 行, 总共 238 个字符.
- 当执行上述代码后(注意此时
setbuf(fp, NULL);
被注释了), 结果为:
end.elapsed time= 0.000092s
- 当将
setbuf(fp, NULL);
的注释去掉, 此时fp
对应的流是不带缓冲的, 代码的执行结果为:
end.elapsed time= 0.000265s
结果在我们的意料之中. 此时由于关闭缓冲后, 系统调用频繁, 所消耗的时间无疑会增多.
显示缓冲的类型以及大小
下面的例子展示了各个流的缓冲类型以及相应的大小:
/* buffer_info.c */
#include <stdio.h>
#include <stdlib.h>void pr_stdio(const char*, FILE*);
int is_unbuffered(FILE*);
int is_linebuffered(FILE*);
int buffer_size(FILE*);#define oops(msg) {perror(msg); exit(1);}int main() {FILE *fp;pr_stdio("stdin", stdin);pr_stdio("stdout", stdout);pr_stdio("stderr", stderr);if ((fp = fopen("/etc/passwd", "r")) == NULL)oops("fopen");if (getc(fp) == EOF)oops("getc error");pr_stdio("/etc/passwd", fp);exit(0);
}void pr_stdio(const char *name, FILE *fp) {printf("stream = %s, ", name);if (is_unbuffered(fp))printf("unbuffered");else if (is_linebuffered(fp))printf("line buffered");elseprintf("fully buffered");printf (", buffer size = %d\n", buffer_size(fp));
}int is_unbuffered(FILE *fp) {return(fp->_flags & _IO_UNBUFFERED);
}int is_linebuffered(FILE *fp) {return(fp->_flags & _IO_LINE_BUF);
}int buffer_size(FILE *fp) {return(fp->_IO_buf_end - fp->_IO_buf_base);
}
程序运行的结果为:
stream = stdin, line buffered, buffer size = 1024
stream = stdout, line buffered, buffer size = 1024
stream = stderr, unbuffered, buffer size = 1
stream = /etc/passwd, fully buffered, buffer size = 4096
标准 IO 库的缓冲区相关推荐
- C++ Primer 第八章 标准IO库
学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区 缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内 ...
- 标准IO库--unix环境高级编程读书笔记
标准IO库是C语言提供的一个库,不光存在于linux中,在windows中也是有的.标准IO库和文件IO的不同是,标准IO库是对文件IO(即系统调用)的封装,并且在用户层添加了一些缓冲区. 文件IO的 ...
- C++ Primer 第八章 标准IO库(转载)
学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区 缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内 ...
- 《UNIX环境高级编程》笔记 第五章-标准IO库
1. 流和FILE对象 在第三章的系统调用都是围绕文件描述符fd的.但是标准I/O库函数操作则是围绕流进行的.当使用标准I/O库打开或创建一个文件时,使用一个流与一个文件关联. 当打开一个流时,标准I ...
- Linux操作系统-标准IO库(2)
Linux操作系统-标准IO库(2)(2015-8-4) 分类:Linux操作系统 打开一个流后,可采用三种不同类型的非格式化I/O对其进行读,写操作. 1. 每次读取一个字符的I/O 2. 每次 ...
- 【Linux】标准IO库
Linux系统的文件IO都是针对文件描述符的,而标准IO(ISO C)的操作则是围绕流进行的,一个最明显的区别是标准IO比Linux文件IO多了缓冲机制.为了使用流,需要用到文件指针即指向FILE结构 ...
- 在标准IO库中,rewind函数作用?
在标准IO库中,rewind函数作用? 将文件内部的位置指针重新指向一个流(数据流/文件)的开头 一个完整的信号生命周期包含4个重要的事件,这4个重要事件分别是? 信号诞生:信号在进程中注册完毕:信号 ...
- Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)
1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...
- Linux后台开发系列之「13.标准 IO 库」
StdIO.png 版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处! 标准 IO 库 上一篇文章我们学习了 5 个底层的 IO 函数,这次我们来学习标准的 I ...
最新文章
- ASP.NET MVC+Bootstrap个人博客之打造清新分页Helper(三)
- python 3读取文件-python3的txt文件读写
- Codeforces Round #741 (Div. 2) D2. Two Hundred Twenty One (hard version) 前缀和 + 分段模型
- iOS5 UI 设计新手段 Storyboard
- Hbase读写数据的原理解析
- 深入探讨SDN拓扑发现机制:新的攻击及实践对策【SDN拓扑】(下)
- 关于ListView中Detail模式下的一些基本操作
- image.merge图像有什么变化_经常用到压缩软件的你,知道什么是无损压缩和有损压缩吗?...
- 类的应用python平均分_【数据科学系统学习】Python # 数据分析基本操作[四] 数据规整化和数据聚合与分组运算...
- 无法添加外键约束的原因(cannot add foreign key constraint)
- fastDFS原理及环境搭建
- abaqus2020安装教程
- [精品]CAD批量处理工具
- 染色基础知识(四)——怎么染?
- Christmas Lights Kata练习
- 项目中引入阿里巴巴图标——iconfont图标的使用-svg格式
- SSM校园外卖订餐系统
- 内核tcp协议栈SACK的处理
- ZZULIOJ:1071: 分解质因子
- 丰田增设电池生产线,加快丰田电动化进程