博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UNIX环境高级编程-标准IO
阅读量:6434 次
发布时间:2019-06-23

本文共 2701 字,大约阅读时间需要 9 分钟。

  • 什么标准IO?
    为了说明这个概念,这里我们讲述一个例子。

门卫老大爷负责把公司里的信件送到到邮局,

下面有两种送法:

1他去一次邮局要花费 10 分钟的时间,而每次最多能送 20 封信,每当信件累计到 20 封的时候他就要动身去邮局了。

2但是当他收到一封加急的邮件时,就会立即去一趟邮局。

系统 IO 就好比每收到一封信时都要去一趟邮局,所以实时性高。而标准 IO 就好比要攒够 20 封信才去一趟邮局,所以吞吐量高,因为用户把信件交到老大爷的手上时就会立即返回,响应速度快,用户体验更好。而我们使用 fflush(3) 之类的函数强制刷新缓冲的时候,就相当于是老大爷收到了一封加急信件需要立即去一趟邮局送信。

标准io与系统io的比较

 

类型 可移植性 实时性 吞吐量 功能
STDIO 受限
SYSIO 自由

 

表格中的每一项都是两者之间相对而言,使用哪种 IO 并没有绝对的好坏之分,要根据实际的需求来决定应该使用哪个。

 

可移植性:

 

  标准 IO 是 C89 支持的函数,所以使用了标准 IO 的程序无论在 Linux 平台还是换成了 Windows 平台,不用修改代码是可以直接编译运行的。

 

  而系统 IO 是由内核直接提供的函数库实现的,不同的操作系统平台上提供的 IO 操作接口是不同的,所以想要移植使用了系统 IO 的程序,必须按照目标平台的 IO 库修改程序并重新调试。

 

  所以你写的程序将来可能在不同的平台上运行,那么最好使用标准 IO 库;如果你的程序是专门针对于某个平台而开发的,那么使用系统 IO 库能够得到我们下面说的其它优势。

 

 

  • 涉及的知识

   流和FILE

 

缓冲:

 

标准io提供缓存的目的是尽可能减少使用read和write调用的数量。它也对每个io流自动地今次那个缓存管理,避免了应用程序需要考虑这一点带来的麻烦。它提供三种类型的缓存

  • 全缓存。这种情况下,当填满标准io缓存后才进行实际io操作。对于驻在磁盘上的文件通常是由标准io库实施全缓存。在一个流上执行第一次io操作时,相关标准io函数通常调用malloc获取使用的缓存。缓存可由标准io例程自动执行刷新(例如当填满一个缓存)或者可以调用fflush()刷新一个流。
  • 行缓存。这种情况下,当输入和输出中遇到新行标准(或者缓存区写满)io库执行io操作。这允许我们一次输出一个字符,但只有在写了一行后才进行实际的io操作。当流设计一个终端时,典型地使用行缓存。
  • 不带缓存。标准io库不对字符进行缓存。如果用标准io函数写若干字符到不带缓存的流中,则相当于用write系统调用函数将这
    一般来说,标准出错是不带缓冲区的,打开终端设备流(如:stdin,stdout)为行缓冲,其他时候为全缓冲;
    这里涉及到了3个函数:
    更改缓冲类型:
    打开和关闭缓冲机制:void setbuf(FILE *steam, char *buf);
    更改流的缓冲模式:int setvbuf(FILE *stream, char *buf, int type, unsigned size);
    刷新缓冲区:
    强制刷新一个流:int fflush(FLIE*stream);

EOF的什么?

    ----------> 详见另一篇博文
 

 

  • 标准IO涉及的常用操作

打开:打开一个流

函数原型:FILE * fopen (const char * path,const char * mode);

返回值:文件顺利打开后,向该流的就会被返回。如果文件打开失败则返回NULL,并把存在中。一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在fopen()后作错误判断及处理。

参数说明:
参数path 串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
mode有下列几种形态 :
r    以 方式打开文件,该文件必须存在。
r+  以可读写方式打开文件,该文件必须存在。
w   打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a    以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。( 符保留)
a+   以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
 
  • 注意:字段“b” 和其组合有些C可能不完全提供所有这些功能 。并且有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,读者注意所用系统的规定。
  • 1.在系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n"
  • 2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。

关闭:关闭一个流

函数原型:int fclose( FILE *fp );
 
返回值:如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)

 。注意:使用fclose()函数就可以把内最后剩余的数据输出到内核缓冲区,并释放和有关的缓冲区。

 

两个常用错误输出函数:

perror:将上一个函数发生错误的原因直接输出到 stdout

函数原型 :void perror const char * str );

参数:str :参数str所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno的值来决定要输出的字符串。

注意:perror输出错误的时效

 

strerror: 将单纯的错误标号转为字符串描述

函数原型 :char*strerror(int errnum);

参数:errnum:错误标号,通常用errno(标准错误号,定义在errno.h中)

返回值:指向错误信息的(即:错误的描述字符串)

 

 

  • 标准IO中遇到的问题

 

转载于:https://www.cnblogs.com/jonwei/articles/6283432.html

你可能感兴趣的文章
全球首家!阿里云获GNTC2018 网络创新大奖 成唯一获奖云服务商
查看>>
Python简单HttpServer
查看>>
Java LinkedList工作原理及实现
查看>>
负载均衡SLB的基本使用
查看>>
Centos 7 x86 安装JDK
查看>>
微信小程序的组件用法与传统HTML5标签的区别
查看>>
Hangfire 使用笔记
查看>>
(C#)Windows Shell 外壳编程系列8 - 同后缀名不同图标?
查看>>
教你彻底学会c语言基础——文件操作
查看>>
如何使用免费控件将Word表格中的数据导入到Excel中
查看>>
seafile服务器配置
查看>>
HyperLedger Fabric 1.2 区块链应用场景(3.1)
查看>>
也谈谈初创公司的技术团队建设
查看>>
阿里云 APM 解决方案地图
查看>>
中国HBase技术社区第一届MeetUp-HBase2.0研讨圆桌会
查看>>
学渣的模块化之路——50行代码带你手写一个common.js规范
查看>>
把前端监控做到极致
查看>>
python——变量
查看>>
subline上装node.js插件
查看>>
python字符串操作实方法大合集
查看>>