Linux系统编程 -- IO缓冲区
标准I/O库提供缓冲的目的是尽可能地减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。
不幸的是,标准I/O库最令人迷惑的也是它的缓冲。
标准I/O提供了三种类型的缓冲:
1、全缓冲:
在填满标准I/O缓冲区后才进行实际I/O操作。常规文件通常是全缓冲的。
2、行缓冲:
当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。这允许我们一次输出一个字符,但只有在写了一行之后才进行实际I/O操作。标准输入和标准输出对应终端设备(如屏幕)时通常是行缓冲的。
3、不带缓冲:
用户程序每次调库函数做写操作都要通过系统调用写回内核(如系统调用函数)。标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备。
下面是各个缓冲区的验证。
1.全缓冲:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("test.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "test\n";fwrite(str, 1, strlen(str), fp); // 往文件写内容while(1); // 程序阻塞在这里return 0;
}
运行程序发现,test.txt并没有内容。因为常规文件通常是全缓冲的,只有缓冲区满了后,才会把内容写到文件中。接下来,我们改一下上面那个例子。
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{FILE *fp = NULL;// 读写方式打开,文件不存在则创建fp = fopen("test.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "test\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("test.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "test\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("test.txt", "w+");if(NULL == fp){printf("open error\n");return 1;}char *str = "test\n";fwrite(str, 1, strlen(str), fp); // 往文件写内容return 0;// 程序正常结束,就算缓冲区没有填满,没有关闭文件,内容也会写进文件。
}
2. 行缓冲:
#include <stdio.h>
int main(int argc, char *argv[])
{printf("hello test");while(1);return 0;
}
运行这个程序,会发现 hello test并没有打印到屏幕上。因为标准输入和标准输出对应终端设备时通常是行缓冲的,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。如下:
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello test\n");while(1);return 0;
}
除了遇到换行符,还有别的方法可以执行I/O操作。
1)缓冲区填满
int main(int argc, char *argv[])
{while(1){ // 循环打印,总有缓冲区填满的可能printf("hello test");}while(1); return 0;
}
2)人为刷新缓冲区
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello test");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系统编程 -- IO缓冲区相关推荐
- Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】
linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...
- Linux系统编程之文件IO
Linux系统编程之文件IO 文件IO第一天 一.标准IO基本概念 1.1c语言函数 (c库函数) 调用实现某一个功能,(API) 1.2系统调用:内核中的程序接口,应用程序和硬件设备之间的中间层 1 ...
- Linux系统编程25:基础IO之亲自实现一个动静态库
本文接:Linux系统编程24:基础IO之在Linux下深刻理解C语言中的动静态库以及头文件和库的关系 文章目录 A:说明 B:实现静态库 C:实现动态库 A:说明 前面说过,库其实就是头文件和和.a ...
- linux原子过程,linux系统编程:IO读写过程的原子性操作实验
所谓原子性操作指的是:内核保证某系统调用中的所有步骤(操作)作为独立操作而一次性加以执行,其间不会被其他进程或线程所中断. 举个通俗点的例子:你和女朋友OOXX的时候,突然来了个电话,势必会打断你们高 ...
- linux系统io编程,Linux系统编程(1) —— 文件IO
本文主要对Linux系统中文件I/O的基本操作进行说明. 在Linux系统编程中,对文件进行处理的流程,通常是: 打开文件 读写文件 关闭文件 Linux内核对每一个进程维护一个打开的文件列表, 该文 ...
- 【Linux】一步一步学Linux系统编程教程汇总(暂时暂停更新......)
00. 目录 文章目录 00. 目录 01. 概述和标准 02. 文件操作 03. 进程概念 04. 进程间通信 05. 多线程 06. 信号 07. 同步与互斥 08. 高级IO 09. 其它 10 ...
- 【Linux系统编程】Linux系统调用
00. 目录 文章目录 00. 目录 01. 系统调用概述 02. 系统调用实现 03. 系统调用和库函数的区别 04. 附录 01. 系统调用概述 系统调用顾名思义,说的是操作系统提供给用户程序调用 ...
- 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)
文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...
- 【学习笔记】Linux 系统编程入门
Linux 系统编程入门 静态库与动态库 静态库命名规则 静态库的制作 静态库使用 动态库制作 动态库使用 加载动态库 静态库的优缺点 动态库的优缺点 Makefile 文件命名 工作原理 变量 模式 ...
- Linux系统编程1——系统函数
文章目录 前言 一.C标准函数与系统函数的区别 1.什么是系统调用 2.文件描述符 3.相关函数 3.1 open函数 3.2 close函数 3.3 read函数 3.4 write函数 3.5 l ...
最新文章
- python用def编写calsum函数_Python函数
- Linux Tomcat安装
- 【OpenCV】OpenCV实战从入门到精通之 -- 常用数据结构和函数(Point、Scalar、Size、Rect、cvtColor)
- dex、apk完整性校验
- 汽车电子测试系统搭建
- ActivityMq的使用(小例子)
- Python爬虫架构
- 二级路由dhcp关闭连不上wifi_如何做到让家里WiFi真正全覆盖的几个布线方案
- 单片机及开发板介绍(学习笔记)
- Opencv裁剪图片大小
- 二进制漏洞挖掘之angr‘s Reaching Definition Analysis(二)
- 使用Clang作为编译器 —— Clang 中的Diagnostic flags
- bboss redis组件使用实例
- html5猜大王游戏,5月8日维护:新副本金兜洞兕大王部分测试
- [附源码]Java计算机毕业设计SSM东北鹿产品售卖网站
- development 和 production 模式的区别
- Mac下转换APFS格式的移动硬盘分区为“Mac OS扩展(日志式)”或其它
- 解决MPS运行中出现Unsupported major.minor version错误问题
- 工作中的遇到的命令备忘录
- JS 唤起QQ对话框