【Linux系统编程】 浅谈标准I/O缓冲区
标准I/O库提供缓冲的目的是尽可能地减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。不幸的是,标准I/O库最令人迷惑的也是它的缓冲。
标准I/O提供了三种类型的缓冲:
1、全缓冲:
在填满标准I/O缓冲区后才进行实际I/O操作。常规文件(如普通文本文件)通常是全缓冲的。
2、行缓冲:
当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。这允许我们一次输出一个字符,但只有在写了一行之后才进行实际I/O操作。标准输入和标准输出对应终端设备(如屏幕)时通常是行缓冲的。
3、不带缓冲:
用户程序每次调库函数做写操作都要通过系统调用写回内核(如系统调用函数)。标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备。
下面是各个缓冲区的验证。
全缓冲:
int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("sunplusedu.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "sunplusedu\n";fwrite(str, 1, strlen(str), fp); // 往文件写内容while(1); // 程序阻塞在这里return 0;
}
运行程序发现,sunplusedu.txt并没有内容。因为常规文件通常是全缓冲的,只有缓冲区满了后,才会把内容写到文件中。接下来,我们改一下上面那个例子。
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("sunplusedu.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "sunplusedu\n";int i = 0;while(i <= 512){ // 缓冲区大小不确定,i的大小只是一个调试值fwrite(str, 1, strlen(str), fp); // 往文件写内容i++;}while(1); // 程序阻塞在这里return 0;
}
上面的例子是循环给文件写内容,让缓冲区有填满的可能,结果发现,文件是有内容的。实际上要想成功给文件写进内容,除了缓冲区填满,还有别的方法。
1)人为关闭文件,就算缓冲区没有填满,内容也会写进文件
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("sunplusedu.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "sunplusedu\n";fwrite(str, 1, strlen(str), fp); // 往文件写内容fclose(fp); // 人为关闭文件,就算缓冲区没有填满,内容也会写进文件while(1); // 程序阻塞在这里return 0;
}
2)程序正常结束,就算缓冲区没有填满,没有关闭文件,内容也会写进文件。
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("sunplusedu.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "sunplusedu\n";fwrite(str, 1, strlen(str), fp); // 往文件写内容return 0;// 程序正常结束,就算缓冲区没有填满,没有关闭文件,内容也会写进文件。
}
行缓冲:
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello sunplusedu");while(1);return 0;
}
运行这个程序,会发现 hello sunplusedu 并没有打印到屏幕上。因为标准输入和标准输出对应终端设备时通常是行缓冲的,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。如下:
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello sunplusedu\n");while(1);return 0;
}
除了遇到换行符,还有别的方法可以执行I/O操作。
1)缓冲区填满
int main(int argc, char *argv[])
{while(1){ // 循环打印,总有缓冲区填满的可能printf("hello sunplusedu");}while(1);return 0;
}
2)人为刷新缓冲区
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello sunplusedu");fflush(stdout); // 人为刷新while(1);return 0;
}
3)程序正常结束
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello sunplusedu");return 0;// 程序正常结束
}
不带缓冲:
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{char *str = "hello sunplusedu.com"; // 有没有\n,缓冲区有没有填满,都没关系write(1, str, strlen(str)); // 往标准输出写内容while(1);return 0;
}
【Linux系统编程】 浅谈标准I/O缓冲区相关推荐
- 【Linux系统编程】IO标准缓冲区
00. 目录 文章目录 00. 目录 01. 缓冲区概述 02. 全缓冲 03. 行缓冲 04. 不带缓冲区 05. 附录 01. 缓冲区概述 标准I/O提供了三种类型的缓冲: 1.全缓冲: 在填满标 ...
- Linux 网络编程——浅谈 C/S 和 B/S 架构
概述 在这个信息急剧膨胀的社会,我们不得不说人类正进入一个崭新的时代,那就是信息时代.信息时代的一个主要而显著的特征就是计算机网络的应用.计算机网络从最初的集中式计算,经过了Client/Server ...
- Linux网络编程——浅谈 TCP 三次握手和四次挥手
一.tcp协议格式 二.三次握手 在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送 syn 包(tcp协议中syn位置1,序号为 ...
- 【Linux系统编程】Linux系统调用
00. 目录 文章目录 00. 目录 01. 系统调用概述 02. 系统调用实现 03. 系统调用和库函数的区别 04. 附录 01. 系统调用概述 系统调用顾名思义,说的是操作系统提供给用户程序调用 ...
- 【Linux系统编程】 Linux系统调用概述
系统调用概述 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组"特殊"接口.用户程序可以通过这组"特殊"接口来获得操作系统内核提供的服务,比如用户可以 ...
- Linux系统编程——Linux系统调用
系统调用概述 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组"特殊"接口.用户程序可以通过这组"特殊"接口来获得操作系统内核提供的服务,比如用户可以 ...
- 【Linux】一步一步学Linux系统编程教程汇总(暂时暂停更新......)
00. 目录 文章目录 00. 目录 01. 概述和标准 02. 文件操作 03. 进程概念 04. 进程间通信 05. 多线程 06. 信号 07. 同步与互斥 08. 高级IO 09. 其它 10 ...
- 【Linux系统编程】进程的控制:结束进程、等待进程结束
结束进程 首先,我们回顾一下 C 语言中 continue, break, return 的作用: continue: 结束本次循环 break: 跳出整个循环,或跳出 switch() 语句 ret ...
- 编程浅谈-以一个初出茅庐的Java程序员视角
编者是一个从事Java开发的普通软件攻城狮,迄今为止,粗粗算来不过刚刚进入编程的世界不过两年,但在这两年的光阴里,每当我抬头仰望星空(苦命加班)时脑海里总有这样一个疑问--"什么是编程&qu ...
最新文章
- anki 新的卡片类型_梁宝川:这一类型Anki卡片,你做了吗?
- HDU3338 Kakuro Extension(最大流+思维构图)
- 零基础带你快速入门consul-难道consul还能这样用?
- Service基本组成 (一)
- luogu1341 无序字母对
- 世界杯后linux进化有感?
- ROS笔记(32) MoveIt!关节控制器
- bootstrap 按钮样式单选效果_【20201117】Bootstrap前端框架学习笔记
- Linux下Gcc生成和使用静态库和动态库详解(转)
- leetcode 13 13. 罗马数字转整数 (python)
- file is not a zip file_如何使用JavaScript解压压缩后的zip文件
- PS如何使用裁切工具
- 剑桥: 一个完美的读书地方
- img标签图片自适应的样式
- 电脑是怎样执行编程语言的
- VMware拟收购云应用管理服务商Wavefront
- Video-based Emotion Recognition Using Multi-dichotomy RNN-DNN
- APP测试之安全性测试
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.20日(2018省赛A组第8题)
- opIndex多级索引笔记
热门文章
- andorid 第一天 搭建环境(于本博另一篇文章 ubuntu下安装andoird SDK相同内容)
- SqlHelper 数据库操作类
- 对集合变量定义赋值_SpringBoot配置加载原理(自定义加载配置)
- php无法查询mysql字母,php – 无法在Multi MYSQL查询语句中获取结果
- C#委托的定义 以及使用方式详解,更简单的理解委托。
- virtualenv杂记
- Css网格布局-Grid布局
- hdu 2586(LCA的离线做法)
- javase学习第10天(形式参数和返回值类型、包、内部类、匿名内部类)
- PRISM概率模型检测器初使用--骰子模型(改进版)