news 2026/6/10 12:59:53

标准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/6/10 16:00:49

函数与面向对象编程知识梳理

目录 第一阶段&#xff1a;基础构建 (The Foundation) 第二阶段&#xff1a;OOP 三大支柱 (The Three Pillars) 第三阶段&#xff1a;工厂与构造技巧 (Creation & Structure) 第四阶段&#xff1a;Pythonic 黑魔法 (Advanced Magic) &#x1f451; 终极代码汇总&#…

作者头像 李华
网站建设 2026/6/10 16:01:49

Dify平台的SDK使用示例生成效率测评

Dify平台的SDK使用示例生成效率测评 在AI应用开发的战场上&#xff0c;时间就是竞争力。当一个企业需要快速上线一款基于大模型的知识问答系统时&#xff0c;传统的开发方式往往意味着数周甚至更久的调试、集成与测试周期——从手动调用API、反复调整提示词&#xff0c;到构建R…

作者头像 李华
网站建设 2026/6/5 13:20:22

qserialport数据帧处理策略:系统学习版

串口通信实战&#xff1a;用 QSerialPort 构建可靠的数据帧解析系统你有没有遇到过这样的情况&#xff1f;设备明明在发数据&#xff0c;Qt 程序也收到了readyRead()信号&#xff0c;但解析出来的却是乱码、错位&#xff0c;甚至程序直接崩溃。调试半天才发现——不是硬件问题&…

作者头像 李华
网站建设 2026/6/10 16:39:49

阴阳师百鬼夜行自动化助手:告别手酸,轻松获取稀有式神

还在为百鬼夜行手动撒豆而手酸吗&#xff1f;阴阳师百鬼夜行自动化助手能够彻底解放你的双手&#xff0c;让你的游戏体验从繁琐操作变成轻松享受。这款基于AI视觉识别的智能助手&#xff0c;通过精准的目标检测和实时跟踪技术&#xff0c;实现高效自动撒豆操作&#xff0c;让你…

作者头像 李华
网站建设 2026/6/3 18:28:43

查询数据库表数据,可以用DataFrame 接收,并遍历

import mysql.connector import pandas as pd# 连接到 MySQL 数据库 conn mysql.connector.connect(host"localhost",user"root",password"password",database"testdb" )# 使用 pandas 读取 MySQL 表的数据并存入 DataFrame df pd.r…

作者头像 李华
网站建设 2026/6/10 9:36:10

AlwaysOnTop窗口置顶工具:彻底告别窗口切换烦恼的终极方案

AlwaysOnTop窗口置顶工具&#xff1a;彻底告别窗口切换烦恼的终极方案 【免费下载链接】AlwaysOnTop Make a Windows application always run on top 项目地址: https://gitcode.com/gh_mirrors/al/AlwaysOnTop 在现代多任务工作环境中&#xff0c;你是否经常面临这样的…

作者头像 李华