标准 IO 库的缓冲区
来源:互联网 发布:天谕男玉虚捏脸数据图 编辑:程序博客网 时间:2024/06/05 10:18
标准 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"); else printf("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 = 1stream = /etc/passwd, fully buffered, buffer size = 4096
阅读全文
0 0
- 标准 IO 库的缓冲区
- 标准库IO缓冲区
- IO标准库:输出缓冲区
- 标准IO库缓冲区buffer
- C++中缓冲区的理解与IO标准库详解
- Linux编程基础:C标准库IO缓冲区与内核缓冲区的区别
- C 标准库IO缓冲区 内核缓冲区(一)
- C 标准库IO缓冲区 内核缓冲区(二)
- linux系统编程之基础必备(四):C 标准库IO缓冲区和内核缓冲区的区别
- linux系统编程之基础必备(四):C 标准库IO缓冲区和内核缓冲区的区别
- linux系统编程之基础必备(四):C 标准库IO缓冲区和内核缓冲区的区别
- 【C++ Primer】【学习笔记】【第八章】标准IO库之:输出缓冲区的管理
- Cpp Primer<<学习IO标准库--输出缓冲区的管理、文件输入与输出_6
- 记一个关于标准IO流缓冲区的有趣例子
- 流,标准IO,低级IO,缓冲区
- 文件IO(标准IO缓冲区)
- 系统缓冲区、内核缓冲区、IO库操作本身的缓冲区 之间联系
- 系统缓冲区、内核缓冲区、IO库操作本身的缓冲区 之间联系
- 鼠标右键 添加可执行jar
- javax.script详解
- mysql 用hfile写入到hbase报错
- python 画中国地图环境搭建(basemap)
- 插入排序
- 标准 IO 库的缓冲区
- HTTP POST GET 本质区别详解
- springboot提示No identifier specified for entity
- 12.11学习心得
- 91. Decode Ways
- 结构体的存储分配问题
- 机器学习笔记(V)线性模型(I)一维最小二乘法
- 关于c++和C的getXXX系列函数
- DataStructureProject(3)