专栏首页开发与安全linux系统编程之基础必备(二):C 标准IO 库函数与Unbuffered IO函数

linux系统编程之基础必备(二):C 标准IO 库函数与Unbuffered IO函数

先来看看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 编程一站式学习》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux系统编程之基础必备(四):C 标准库IO缓冲区和内核缓冲区的区别

    1.C标准库的I/O缓冲区          UNIX的传统 是Everything is a file,键盘、显示器、串口、磁盘等设备在/dev 目录下都有...

    s1mba
  • linux系统编程之基础必备(七):read/write函数与(非)阻塞I/O的概念

    一、read/write 函数 read函数从打开的设备或文件中读取数据。 #include <unistd.h> ssize_t read(int fd,...

    s1mba
  • linux网络编程之socket(十三):epoll 系列函数简介、与select、poll 的区别

    一、epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_cr...

    s1mba
  • 论文解读——基于改进纯追踪模型的农机路径跟踪算法研究

    《基于改进纯追踪模型的农机路径跟踪算法研究》是期刊《农业机械学报》在2020年7月3日网络首发的一篇论文。《农业机械学报》目前属于三类高质量期刊,是EI收录期刊...

    路径跟踪快讯
  • 数据标签太长了,怎么办……

    今天给大家讲解在图表中长数据标签的特殊处理方法! ▽ 如果你的图表要求必须添加数据标签的话 最大的困惑就是对于哪些特别长的数据标签 加上之后图表是这样的 ? 看...

    数据小磨坊
  • spring cloud 加入配置中心后的 部分 配置文件优先级

    bootstrap.properties:位于jar包外的优先级最高 application.properties:配置中心的文件 > 命令行配置 > 本地ac...

    似水的流年
  • 机器学习常见的聚类算法(上篇)

    陈浩然,北大在读,个人网站:chrer.com,里面记录了机器学习、深度学习的系统学习笔记,欢迎大家访问,感谢分享!

    double
  • 机器学习(8)——其他聚类层次聚类画出原始数据的图小结

    层次聚类 紧接上章,本章主要是介绍和K-Means算法思想不同而的其他聚类思想形成的聚类算法。 k-means算法却是一种方便好用的聚类算法,但是始终有K值选择...

    DC童生
  • 业界 | 数据科学正从这七个方向颠覆金融界

    近年来,数据科学和机器学习在应对金融领域诸多任务的处理能力已经成为大家关注的焦点。公司希望知道新技术能够为公司带来什么改进以及它们如何重塑公司的经营策略。

    大数据文摘
  • 科学瞎想系列之九十一 NVH那些事(2)

    【图片部分来自网络如有侵权敬请邮箱联系。欢迎原文转发到朋友圈,未经许可的媒体平台谢绝转载,如需转载或合作请邮件联系。联系邮箱laolicsiem@126.com...

    标准答案

扫码关注云+社区

领取腾讯云代金券