news 2026/4/15 9:10:01

标准IO之流与缓冲

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
标准IO之流与缓冲

文章目录

  • 流(FILE)
    • 文本流与二进制流
    • 流的缓冲类型
      • 无缓冲
      • 行缓冲
      • 全缓冲
      • 修改缓冲类型
  • 标准I/O 由ANSI C标准定义,主流操作系统上都实现了C库
  • 标准I/O通过缓冲机制减少系统调用,实现更高的效率

标准IO是C函数库的常见IO操作接口(对操作系统提供的系统调用进行封装,进一步降低与硬件的耦合),提供了缓冲机制,减少触发系统调用次数,实现了更高的效率

- fopen 函数是由封装 open 函数实现 - fclose 函数是由封装 close 函数实现 - fread 函数是由封装 read 函数实现 - fwrite 函数是由封装 write 函数实现 - fseek 函数是由封装 lseek 函数实现
  • 标准IO用一个结构体类型来存放打开的文件的相关信息,所有操作都是围绕FILE来进行
  • 查看FILE结构的定义:
    • vi /usr/include/stdio.h
    • vi /usr/include/bits/types/struct_FILE.h

  • 文件IO和标准IO对比

流(FILE)

  • 标准IO用一个结构体类型来存放打开的文件的相关信息
  • 标准I/O的所有操作都是围绕FILE来进行
  • FILE又被称为流(stream),文本流/二进制流

文本流与二进制流

  • 文本流:数值以字符形式,每一个字符都是一个字节,对应ASCII码值。文本流中的数据可以显示和打印出来,都是用户可以读懂的信息
  • 二进制流:流中的数据是按照二进制编码的方式(值的方式)来存放文件。二进制数据也可在屏幕上显示,但其内容无法读懂
  • 二进制流比文本流更节省空间,且不用对换行符进行转换,这样可以大大加快流的速度,提高效率,二进制流没有行长度的限制,也可以包含空字符(NULL)。
  • 因此,对于含有大量数据信息的数字流,可以采用二进制流的方式;对于含有大量字符信息的流,则采用文本流的方式

流的缓冲类型

  • 标准I/O预定义3个流,程序运行时自动打开
名称文件描述符(值)常量缓冲类型
标准输入流0STDIN_FILENOstdin通常是行缓冲
标准输出流1STDOUT_FILENOstdout当连接到终端时,通常是行缓冲
标准错误流2STDERR_FILENOstderr默认是无缓冲,立即输出

无缓冲

  • 数据直接写入文件,流不进行缓冲
#include<stdio.h>#include<unistd.h>intmain(intargc,constchar*argv[]){perror("aaaa");#if0while(1){sleep(1);}#endifreturn0;}
  • 程序正常结束会主动刷新缓冲区

行缓冲

  • 当在输入和输出中遇到换行符(‘\n’)时,会自动触发刷新
  • 当缓冲区达到其容量限制时,会自动触发刷新
  • 当 main() 函数返回或调用 exit() 时,所有缓冲区的数据都会被刷新
  • 当流和一个终端关联时,典型的行缓冲
    • printf("Enter name: "); // 可能不会立即显示
    • scanf("%s", name); // 读取前会刷新 stdout
#include<stdio.h>#include<unistd.h>intmain(intargc,char*argv[]){inti=0;#if0do{printf("a");i++;}while(i<100);#else//1024do{printf("a");i++;}while(i<1025);#endifsleep(10);return0;}
  • \n是换行字符,printf支持的是行缓冲,加上\n刷新了行缓冲,实现输出
  • 不同的环境是不一样的大小,这里标准输出的行缓冲是1024个字节。

全缓冲

  • 当流的缓冲区无数据或无空间触发刷新
  • 当 main() 函数返回或调用 exit() 时,所有缓冲区的数据都会被刷新
  • 关闭文件或程序正常结束触发刷新

  • 全缓冲大小和系统有关系,在Ubuntu 14.04 32位系统、Ubuntu 22.04 64位系统测试是4096字节
#include<stdio.h>#include<unistd.h>intmain(intargc,char*argv[]){FILE*fd=fopen("a.txt","a+");fprintf(fd,"a");//读、写缓冲区大小printf("%d ",fd->_IO_buf_end-fd->_IO_buf_base);// 4096inti=0;do{fprintf(fd,"a");i++;}while(i<4098);//测试写指针偏移量printf("%d",fd->_IO_write_ptr-fd->_IO_write_base);// 3sleep(5);return0;}

修改缓冲类型

  • 通过setbuf、setvbuf函数修改缓冲类型
  • setbuf(stdout, NULL);关闭缓冲,将缓冲策略修改为无缓冲
#include<stdio.h>#include<unistd.h>intmain(intargc,char*argv[]){printf("a");sleep(5);//a是行缓冲,原则是不输出的,这时关闭缓冲setbuf(stdout,NULL);//模式是无缓冲后,先把缓冲中的a刷了出来,b再立马输出printf("b");sleep(5);return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 16:09:40

35、深入解析 SEO:现状、策略与未来趋势

深入解析 SEO:现状、策略与未来趋势 在当今数字化时代,搜索引擎优化(SEO)已成为企业网络营销的重要组成部分。为了深入了解 SEO 的现状、面临的挑战以及未来的发展趋势,我们采访了三位行业专家,他们分别是 SPH Associates 的顾问 Stephen Harris、Fast Search 的产品营销…

作者头像 李华
网站建设 2026/4/10 6:41:31

音乐解锁实战指南:一键解决加密音乐格式转换难题

音乐解锁实战指南&#xff1a;一键解决加密音乐格式转换难题 【免费下载链接】unlock-music-electron Unlock Music Project - Electron Edition 在Electron构建的桌面应用中解锁各种加密的音乐文件 项目地址: https://gitcode.com/gh_mirrors/un/unlock-music-electron …

作者头像 李华
网站建设 2026/4/11 21:21:14

15B小模型如何挑战千亿级性能?Apriel-1.5推理王来了

15B小模型如何挑战千亿级性能&#xff1f;Apriel-1.5推理王来了 【免费下载链接】Apriel-1.5-15b-Thinker 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/Apriel-1.5-15b-Thinker 导语&#xff1a;ServiceNow推出的150亿参数多模态推理模型Apriel-1.5-15b-Thin…

作者头像 李华
网站建设 2026/4/12 14:49:01

Dify在SEO标题生成中的关键词布局技巧

Dify在SEO标题生成中的关键词布局技巧 在内容为王的时代&#xff0c;一个网页能否被用户点击&#xff0c;往往取决于它的标题是否足够吸引人。而这个“吸引力”背后&#xff0c;其实是一场搜索引擎优化&#xff08;SEO&#xff09;与用户心理的双重博弈。传统的标题创作依赖编辑…

作者头像 李华
网站建设 2026/4/13 10:15:38

微信消息智能转发革命:wechat-forwarding 5分钟极速上手全攻略

在日常工作和生活中&#xff0c;我们经常需要在多个微信群之间同步重要信息&#xff0c;手动转发不仅耗时费力&#xff0c;还容易遗漏关键内容。今天介绍的 wechat-forwarding 开源工具&#xff0c;将彻底改变你的消息管理方式&#xff0c;实现微信群消息的智能自动转发。 【免…

作者头像 李华
网站建设 2026/4/12 23:09:28

Dify平台的古代语言风格模仿能力测试

Dify平台的古代语言风格模仿能力测试 在数字人文与AI技术交汇的今天&#xff0c;一个引人深思的问题浮现&#xff1a;机器能否真正“读懂”古文&#xff1f;更进一步——它是否能以古人之口吻言说&#xff0c;用《论语》的简练、唐诗的韵律、宋词的婉约来回应现代人的提问&…

作者头像 李华