先来看看C标准I/O库函数是如何用系统调用实现的。

fopen(3)

调用open(2)打开指定的文件,返回一个文件描述符(就是一个int 类型的编号),分配一 个FILE 结构体, 通常里面包含了:

  • 文件fd
  • 缓冲区指针
  • 缓冲区长度
  • 当前缓冲区读取长度
  • 出错标志

返回这 个FILE 结构体的地址。

fgetc(3) 
通过传入的FILE *参数找到该文件的描述符、I/O缓冲区和当前读写位置,判断能否从I/O缓冲 区中读到下一个字符,如果能读到就直接返回该字符,否则调用read(2),把文件描述符传进 去,让内核读取该文件的数据到I/O缓冲区,然后返回下一个字符。注意,对于C标准I/O库来 说,打开的文件由FILE *指针标识,而对于内核来说,打开的文件由文件描述符标识,文件描述符从open 系统调用获得,在使用read 、write 、close 系统调用时都需要传文件描述符。

fputc(3) 
判断该文件的I/O缓冲区是否有空间再存放一个字符,如果有空间则直接保存在I/O缓冲区中并 返回,如果I/O缓冲区已满就调用write(2) ,让内核把I/O缓冲区的内容写回文件。

fclose(3) 
如果I/O缓冲区中还有数据没写回文件,就调用write(2) 写回文件,然后调用close(2) 关闭文 件,释放FILE 结构体和I/O缓冲区。

以写文件为例,C标准I/O库函数(printf(3) 、putchar(3) 、fputs(3) )与系统调用write(2) 的关 系如下图所示。

库函数与系统调用的层次关系

open 、read 、write 、close 等系统函数称为无缓冲I/O(Unbuffered I/O)函数,因为它们位于C标 准库的I/O缓冲区的底层。用户程序在读写文件时既可以调用C标准I/O库函数,也可以直接调用 底层的Unbuffered I/O函数,那么用哪一组函数好呢?

用Unbuffered I/O函数每次读写都要进内核,调一个系统调用比调一个用户空间的函数要慢很 多,所以在用户空间开辟I/O缓冲区还是必要的,用C标准I/O库函数就比较方便,省去了自己 管理I/O缓冲区的麻烦。

用c标准I/O库函数要时刻注意I/O缓冲区和实际文件有可能不一致,在必要时需调 用fflush(3) 。

我们知道UNIX的传统是Everything is a file,I/O函数不仅用于读写常规文件,也用于读写设 备,比如终端或网络设备。在读写设备时通常是不希望有缓冲的,例如向代表网络设备的文 件写数据就是希望数据通过网络设备发送出去,而不希望只写到缓冲区里就算完事儿了,当网络设备接收到数据时应用程序也希望第一时间被通知到,所以网络编程通常直接调 用Unbuffered I/O函数。

C标准库函数是C标准的一部分,而Unbuffered I/O函数是UNIX标准的一部分,在所有支持C语言的 平台上应该都可以用C标准库函数(除了有些平台的C编译器没有完全符合C标准之外),而只有 在UNIX平台上才能使用Unbuffered I/O函数,所以C标准I/O库函数在头文件stdio.h中声明, 而read 、write 等函数在头文件unistd.h 中声明。在支持C语言的非UNIX操作系统上,标准I/O库的 底层可能由另外一组系统函数支持,例如Windows系统的底层是Win32 API,其中读写文件的系统 函数是ReadFile 、WriteFile 。

参考: 《linux c 编程一站式学习》

转载于:https://www.cnblogs.com/alantu2018/p/8472709.html

C 标准IO 库函数与Unbuffered IO函数相关推荐

  1. Linux标准IO定位函数,Linux C标准IO库函数详解 一

    1.open/close函数 open函数可以打开或者创建一个文件. #include #include #include int open(const char *pathname, int fla ...

  2. 在标准IO库中,rewind函数作用?

    在标准IO库中,rewind函数作用? 将文件内部的位置指针重新指向一个流(数据流/文件)的开头 一个完整的信号生命周期包含4个重要的事件,这4个重要事件分别是? 信号诞生:信号在进程中注册完毕:信号 ...

  3. Linux下标准I/O库函数fopen、fclose函数的使用方法

    fopen.fclose使用方法详解 1.I/0的管理分类 1.1打开流 1.2关闭流 1.3代码实操 1.4运行截图 无论是编写系统程序还是应用程序,都离不开I/O这个重要的环节. 相对于低级的I/ ...

  4. Linux C: IO库函数,文件流缓冲,变参函数

    一.I/O 库函数与系统调用 在Linux 中有很多关于IO(输入输出)的库函数,其大部分都存在 stdio.h 头文件中.例如fopen,fread,fwrite,fseek,fclose , 这些 ...

  5. linux read函数_浅谈Linux内核IO体系之磁盘IO

    前言 Linux I/O体系是Linux内核的重要组成部分,主要包含网络IO.磁盘IO等.基本所有的技术栈都需要与IO打交道,分布式存储系统更是如此.本文主要简单分析一下磁盘IO,看看一个IO请求从发 ...

  6. 【多线程】0.理解一下5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO

    5种IO模型.阻塞IO和非阻塞IO.同步IO和异步IO 看了一些文章,发现有很多不同的理解,可能是因为大家入切的角度.环境不一样.所以,我们先说明基本的IO操作及环境. 本文是在<UNIX网络编 ...

  7. C++primer第八章 IO库 8.1 IO类

    IO库设施 istream  (输入流)类型,提供输入操作. ostream (输出流)类型,提供输出操作. cin,-个 istream对象,从标准输入读取数据. cout, 一个ostream对象 ...

  8. (转载) 标准C中的字符串操作函数

    字符串操作函数 目录: 1.  memset   初始化字串 2.  strlen       字串长度 3.  strcpy / strncpy  拷贝字串 4.  strcat / strncat ...

  9. 同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区分

    POSIX 首先了解下什么是posix 可移植操作系统接口(英语:Portable Operating System Interface,缩写为POSIX)是IEEE为要在各种UNIX操作系统上运行软 ...

最新文章

  1. jquery按钮禁用(全)
  2. CentOs 6.3_64静默安装oracle11g_r2
  3. 神策数据张涛:AARRR 模型面临的新挑战
  4. RabbitMQ 的概念
  5. SAP CRM IBASE保存的逻辑分析
  6. 微软高管解读财报:努力创新云基础架构
  7. 可以批量修改文件名、文件后缀的实用工具
  8. Kotlin 学习笔记(七)—— Kotlin类与对象之属性与字段
  9. Sublime Text 2删除行尾空格
  10. 1025. 反转链表 (25)-浙大PAT乙级真题
  11. 学校教材管理系统html,学校教材管理系统
  12. access通过身份证号提取性别_身份证号码男女函数(excel中关于18位身份证号的提取性别公式)...
  13. 射频IC行业为何这么惨?——RFIC的尴尬的现实和迷茫的未来
  14. 《缠中说禅108课》58:图解分析示范三
  15. Cocos2d-x制作《单机斗地主》源码解剖1:创建一副扑克牌
  16. sd卡驱动分析 linux,linux下SD卡驅動分析(一)
  17. UPCOJ-5344 - 被子 - 瞎搞
  18. Android 7.0正式版工厂镜像下载
  19. unity 贴图材质的调整-uv通道修改
  20. Pychram连接mist远程服务器踩坑指南

热门文章

  1. 关于解决Permission is only granted to system apps
  2. WCF部署到IIS不使用svc文件
  3. zoj 2526(一道很好的最短路应用题)
  4. initramfs 工作原理
  5. Java 理论与实践:您的小数点到哪里去了?(转载)
  6. Nacos版本升级1.1.3 >> 1.3.1 —>再升级至1.3.2
  7. SpringMVC请求中的普通、POJO、数组集合类型传参与类转换器
  8. Spring事务详解与使用
  9. emlog过滤html,Emlog 搜索优化 标题 + 全文搜索
  10. B端产品如何做好从1到10的架构搭建?