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 编程一站式学习》
C 标准IO 库函数与Unbuffered IO函数的更多相关文章
- 标准c库函数和linux系统函数的关系
c库IO函数的工作流程 c库函数与系统函数的关系 虚拟地址空间 文件描述符
- C标准I/O库函数与Unbuffered I/O函数
一.C标准I/O库函数.Unbuffered I/O函数 1. C标准I/O库函数是如何用系统调用的 fopen(3) 调用open(2)打开制定的文件,返回一个文件描述符(一个int类型的编号),分 ...
- UNIX环境高级编程——标准I/O库函数和Unbuffered I/O函数
以写文件为例,C标准I/O库函数(printf(3) .putchar(3) .fputs(3) )与系统调用write(2) 的关 系如下图所示. 库函数与系统调用的层次关系 open .read ...
- nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模块的Javascript
Javascrip本身不带IO功能,nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模 ...
- Python文件操作函数os.open、io.open、内置函数open之间的关系
Python提供了多种文件操作方式,这里简单介绍os.open.io.open.内置函数open之间的关系: 一.内置函数open和io.open实际上是同一个函数,后者是前者的别名: 二.os.op ...
- Linux Network IO Model、Socket IO Model - select、poll、epoll
目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...
- Java IO系列之一:IO
1. 概述 Java IO一般包含两个部分: 1.java.io包中堵塞型IO: 2.java.nio包中的非堵塞型IO,通常称为New IO. java.io包下,分为四大块近80个类: 1.基于字 ...
- 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO
完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...
- 事件驱动模型 IO多路复用 阻塞IO与非阻塞IO select epool
一.事件驱动 1.要理解事件驱动和程序,就需要与非事件驱动的程序进行比较.实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的.早期则存在许多非事件驱动的程序,这样的程序,在需要等待 ...
随机推荐
- iOS开发-xCode代码托管到GitHub
xCode默认的是由源代码管理工作Git,Android Studio内置的也有,之前写过两篇关于Window托管Android代码到GitHub的文章,一直想写篇关于Mac上托管代码的到文章,今天终 ...
- GO语言基础语法
1. Go项目的目录结构 一般的,一个Go项目在GOPATH下,会有如下三个目录: project --- bin --- pkg --- src 其中,bin 存放编译后的可执行文件:p ...
- 【cocos2dx开发技巧8】自定义控件-使自定义控件具有RGBA特性
转发,请保持地址:http://blog.csdn.net/stalendp/article/details/9948545 虽然CCNodeRGBA,CCLayerRGBA,sprite等提供颜色和 ...
- Mongo读书笔记2 -- 数据类型
Mongo有多种类型的collection, 默认的是随着document 数目的增多自动增大; 还有一些collection被称为capped collection, 只能包含固定数目的docu ...
- 输入框提示文字跨浏览器的placeholder-jQuery版
<script type="text/javascript" src="jquery-1.7.2.min.js"></script> & ...
- (C语言)memcpy函数原型的实现
在网上看到一道题,实现一个memcpy函数,于是查了一下memcpy的函数原型,如下: void* memcpy(char *strDest, const char *strSrc, int Coun ...
- iOS用户体验之-导航之道
iOS用户体验之-导航之道 用户不会意识到有导航指向的存在除非他遇到非预期的效果. 能够说导航时逻辑跳转的节点.所以导航对用户体验是至关重要的. iOS中有三种类型的导航.每一种适合不同类型的app. ...
- 虎嗅: 小米盒子vs乐视盒子
机顶盒并非新鲜概念,可一旦和互联网发生了跨界关系,就会产生奇妙的反应.自年初小米盒子和乐视盒子分别在突破重重阻碍成功发售之后,互联网企业进军硬件制造领域的趋势愈发明显.今天我们拿到了两家的盒子产品,从 ...
- mkdir命令(转)
原文:http://www.cnblogs.com/peida/archive/2012/10/25/2738271.html linux mkdir 命令用来创建指定的名称的目录,要求创建目录的用户 ...
- Java从零开始学十五(继承)
一.继承作用 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一个类B的属性和方法的一种途径 类A可以有自己的属性和方法 ...