Linux I/O函数(beta)

原创 2017年01月03日 16:06:18

在学习使用C语言的时候,我们总会遇到各种各样的输入输出函数。fopen,open,read,write,scanf,printf等等。那么到底什么时候应该用什么,我么该如何选择呢,我之前总是有疑问。在认真学习了《csapp》《apue》之后,总算是有点眉目了。下面做一个记录。

首先明确一下什么是输入输出,输入输出是在主存和外部设备之间拷贝数据的过程。输入输出是相对主存而言的。在编写C语言程序的时候,我们可能会遇到两类I/O函数,一类是系统I/O,一类是标准I/O。

系统I/O:
open,read, write,lseek,stat,close等
标准I/O:
fopen, fdopen, fread, fwrite, fscanf, fprintf, sscanf, sprintf,fgets,fputs
fflush, fseek, fclose等

标准I/O是系统I/O带缓冲的替代品,主要用来克服系统I/O的性能不足,是磁盘和终端设备I/O之选。
大多数C程序员在他们的职业生涯中只使用标准I/O,而从不涉及低级I/O函数。

标准I/O有一些限制:
限制一:
跟在输出函数之后的输入函数,如果中间没有插入对fflush/fseek/fsetpos或者rewind的调用,一个输入函数不能跟随在一个输出函数之后。fflush函数清空输出流的缓冲区,实际就是写入文件,这样的话,输入的数据就不会和因为输出而填在输入缓冲区的数据弄混了。后三个函数通过使用lseek函数来重置当前的文件位置。
限制二:
跟在输入函数之后的输出函数,如果中间没有插入fseek/fsetpos或者rewind的调用,一个输出函数不能跟随在一个输入函数之后,除非该输入函数遇上了一个EOF。因为这样的话,输出函数会连带缓冲区中的数据一起输出到文件中。

fseek,fsetpos和rewind都是改变文件表的当前位置指针,很好理解。
在这里的关键是fflush函数的理解,为什么对于限制二不能用fflush。
根据Linux man手册,
fflush有以下原型
int fflush(FILE *stream)
对于输出流,fflush将用户缓冲区的数据写到输出对象,或者通过流的写函数来更新流。对于可定位文件相对应的输入流(磁盘文件,但不能是管道或者终端设备),fflush抛弃
从对应文件中取出到缓冲区中但是还没有被应用所用的数据。
如果stream参数是NULL, fflush flush所有打开的输出流。
fflush并不会改变文件表的当前位置。
在对网络使用标准I/O的时候会遇到问题。因为对套接字使用lseek函数是非法的。
对流I/O的第一个限制能够通过采用在每个输入操作前刷新缓冲区来满足(实验验证ubuntu16.04,无论是否使用fflush效果是一样的,相信在fread实现中有内置的fflush),然而要满足第二个限制
唯一的办法是,对同一个打开的套接字描述符打开两个流,一个用来读一个用来写。但是fclose(fpin)和fclose(fout),试图关闭同一个底层的套接字描述符,所以第二个close会失败,对于顺序程序来说不是问题,但是对于线程化的程序来说关闭一个已经关闭的描述符会导致灾难(为什么会导致灾难)。

因此《csapp》建议使用健壮的rio函数,如果需要格式化的输出,使用sprintf函数在存储器中格式化一个字符串,然后用rio_writen把它发送到套接字接口(直接不用缓冲区,相比原始接口仅仅重启中断的系统调用)。如果需要格式化输入,使用rio_readlineb来读一个完整的文本行,然后用sscanf从文本行中提取不同的字段。实际上就是说输出就不要用buffer了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

嵌入式LINUX下I/O资源的实现、管理和操作

作者:wincemobile 转自:http://blog.csdn.net/wincemobile/article/details/5898990 几乎每一种外设都是通过读写设备...
  • whw8007
  • whw8007
  • 2014年02月12日 08:57
  • 635

Linux 系统应用编程——标准I/O

标准I/O的由来         标准I/O指的是ANSI C 中定义的用于I/O操作的一系列函数。         只要操作系统安装了C库,标准I/O函数就可以调用。换句话说,如果程序中使用的是标准...
  • zqixiao_09
  • zqixiao_09
  • 2016年01月05日 20:12
  • 992

Linux 下I/O多路复用总结

 select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但se...
  • hsy12342611
  • hsy12342611
  • 2016年04月07日 15:45
  • 2768

linux 异步I/O的实现

知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上。预先知道这些数据的位置,所以预先发起异步IO读请求。等到真正需要用到...
  • zhang_shuai_2011
  • zhang_shuai_2011
  • 2012年06月20日 10:50
  • 4758

C语言标准I/O函数及其特点总结

C语言的标准I/O库通过系统调用同内核打交道,内核通过驱动和硬件打交道。由于CPU要处理很多任务,所以和低速的I/O的交互一般要经过中间的缓存。    标准I/O库有几个常用函数,虽然很常见,但是其...
  • a1510685338
  • a1510685338
  • 2015年03月16日 20:24
  • 1352

Linux下测试磁盘I/O性能

hdparm hdparm -tT /dev/sda 测试硬盘速度 hdparm -A1 /dev/sda 开启硬盘预读取功能 hdparm -c3 /dev/sda 开启硬盘32位 hd...
  • Genius_LG
  • Genius_LG
  • 2014年05月31日 14:32
  • 820

linux下磁盘I/O查看

Linux系统出现了性能问题,一般我们可以通过top、iostat、free、vmstat等命令 来查看初步定位问题。其中iostat可以给我们提供丰富的IO状态数据。 1. 基本使用 $iost...
  • sd4015700
  • sd4015700
  • 2014年04月11日 15:22
  • 2611

Linux异步I/O

Linux中最常用的输入/输出(I/O)模型是同步I/O。在这个模型中,当请求发出之后,应用程序就会阻塞,直到请求满足为止。这是很好的一种解决方案,因为调用应用程序在等待I/O请求完成时不需要占用任何...
  • skywalker_leo
  • skywalker_leo
  • 2015年09月05日 11:06
  • 432

【重要】Linux I/O模型

socket阻塞与非阻塞,同步与异步、I/O模型 分类: c/c++ socket网络编程2012-04-12 16:35 32926人阅读 评论(22) 收藏 举报 socket...
  • chenchong_219
  • chenchong_219
  • 2014年06月29日 15:10
  • 1639

linux系统性能监控--I/O利用率

尽管整体的处理器速度、 内存大小以及 I/O执行速度在不断提高,但 I/O操作的吞吐率和延迟性能仍然要比等价的内存访问操作低多个数量级。另外,由于许多工作负荷都拥有重要的I/O组件,I/O处理很容易成...
  • ctthunagchneg
  • ctthunagchneg
  • 2016年10月17日 20:12
  • 1554
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux I/O函数(beta)
举报原因:
原因补充:

(最多只允许输入30个字)