《Unix环境高级编程》读书笔记 第5章-标准I/O流

王朝学院·作者佚名  2016-05-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

《Unix环境高级编程》读书笔记 第5章-标准I/O流1. 引言标准I/O库由ISO C标准说明,由各个操作系统实现标准I/O库处理很多细节,如缓冲区分配、以优化的块长度执行I/O等。这些处理使用户不必担心如何使用正确的块长度,这使得它便于用于使用,但是如果不深入地了解I/O库函数的操作,也会带来一些问题。2. 流和FILE对象第3章中,所有I/O函数都是围绕文件描述符的;对于标准I/O库,它们的操作是围绕流FILE *进行的,称其为文件指针。FILE对象通常是一个结构,它包括了标准I/O库为管理该流需要的所有信息,包括用于实际I/O的文件描述符、指向用于该流缓冲区的指针、缓冲区的长度、当前在缓冲区中的字符数以及出错标志等。

标准I/O文件流可用于单字节或多字节(“宽”)字符集。

流的定向决定了所读、写的字符是单字节还是多字节的。当一个流最初被创建时,它并没有定向。若在为定向的流上使用一个多字节I/O函数,则将流的定向设置为宽定向的;若在为定向的流上使用一个单字节I/O函数,则将流的定向设置为字节定向的。#include <stdio.h>#include <wchar.h>int fwide(FILE *fp, int mode);Returns: positive if stream is wide oriented, negative if stream is byte oriented, or 0 if stream has no orientation根据mode参数的不同字,fwide函数执行不同的工作。mode为负,则字节定向;mode为正,则宽定向;mode为0,则不设置流的定向,fwide返回标识该流定向的值注意,fwide并不改变已定向流的定向3. 标准输入、标准输出、标准错误3个标准I/O流通过预定义文件指针(即FILE *) stdin、stdout、stderr加以引用。4. 缓冲标准I/O库提供缓冲的目的是尽可能减少使用read和write调用的次数。它对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。遗憾的是,标准I/O库最令人迷惑的也是它的缓冲。

标准I/O提供了以下3种类型的缓冲:

全缓冲。在填满标准I/O缓冲区后才进行实际I/O操作。对于驻留在磁盘上的文件通常由标准I/O库实施全缓冲。缓冲区可由标准I/O例程自动地冲洗(flush),也可通过调用函数fflush冲洗一个流。术语flush有两种意思:在标准I/O库方面,flush(冲洗)意味着缓冲区中的内容写到磁盘上;在终端驱动程序方面,flush(刷清)表示丢弃已存储在缓冲区中的数据。行缓冲。当输入或输出中遇到换行符时,标准I/O库执行I/O操作。当流涉及一个终端时,通常使用行缓冲。对于行缓冲有两个限制:只要填满了缓冲区,即使还没遇到换行符,也进行I/O操作;任何时候只要通过标准I/O库要求从(a)一个不带缓冲的流,或者(b)一个行缓冲的流得到输入数据,那么就会flush所有行缓冲输出流。不带缓冲。标准I/O库不对字符进行缓冲存储。如fputs函数。标准错误流stderr通常是不带缓冲的。ISO C要求下列缓冲特征:

当且仅当标准输入和标准输出并不指向交互式设备时,它们才是全缓冲的标准错误决不会是全缓冲的很多系统默认使用下列类型的缓冲:

标准错误是不带缓冲的若是指向终端设备的流,则是行缓冲的;否则是全缓冲的#include <stdio.h>void setbuf(FILE *restrict fp, char *restrict buf );// 使用该函数打开或关闭缓冲机制。参数buf必须指向一个长度为BUFSIZ的缓冲区;或为NULL以关闭缓冲int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size); Returns: 0 if OK, nonzero on error上面两个函数必须在流被打开后,且对流执行任何一个其他操作之前调用mode参数:_IOFBF全缓冲、_IOLBF行缓冲、_IONBF不带缓冲如果指定全缓冲或行缓冲,则buf和size可选择地指定一个缓冲区及其长度。若流带缓冲而buf是NULL,则标准I/O库将自动地为该流分配适当长度的缓冲区。[flash=500,400]http://s1.knowsky.com/20150728/egospkrdzy247.png[/flash]#include <stdio.h>int fflush(FILE *fp); // 若fp为NULL,则导致所有输出流被冲洗Returns: 0 if OK, EOF on error5. 打开流下列3个函数打开一个标准I/O流#include <stdio.h>FILE *fopen(const char *restrict pathname, const char *restrict type);FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);// 在一个指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流FILE *fdopen(int fd, const char *type); // 取一个已有的文件描述符,并使一个标准的I/O流与该描述符相结合All three return: file pointer if OK, NULL on error打开标准I/O流的type参数[flash=500,400]http://s1.knowsky.com/20150728/5wq3rzhejf247.png[/flash]字符b,代表二进制。但Unix内核并不对文本文件和二进制文件进行区分注意:在指定w或a类型创建一个新文件时,我们无法说明该文件的访问权限位;而open和creat可以如果以读和写类型打开一个文件时(type中带+号),具有下列限制:

如果中间没有fflush、fseek、fsetpos或rewind,则在输出的后面不能直接跟随输入如果中间没有fseek、fsetpos或rewind,或者一个输入操作没有到达文件尾端,则在输入操作之后不能直接跟随输出打开一个标准I/O流的6种不同方式[flash=500,400]http://s1.knowsky.com/20150728/emqklptbld047.png[/flash]

除非流引用终端设备,否则按系统默认,流被打开是全缓冲的。若流引用终端设备,则该流是行缓冲的。#include <stdio.h>int fclose(FILE *fp);Returns: 0 if OK, EOF on error当一个进程正常终止时(调用exit或从main函数返回),则所有带未写缓冲数据的标准I/O流都被冲洗,所有打开的标准I/O流都被关闭。6. 读和写流一旦打开了流,可在3种不同类型的非格式化I/O中进行选择,对其进行读、写操作

每次一个字符的I/O每次一行的I/O直接I/O(二进制I/O、面向记录的I/O、一次一个对象的I/O)在大多数实现中,为每个流在FILE对象中维护了两个标志:

出错标志文件结束标志区分是出错还是到达文件尾端,因为这两种情况下返回值相同

#include <stdio.h>int ferror(FILE *fp);int feof(FILE *fp);Both return: nonzero (true) if condition is true, 0 (false) otherwisevoid clearerr(FILE *fp); // 调用clearerr可以清除这两个标志7. 每次一个字符的I/O输入函数#include <stdio.h>int getc(FILE *fp); // 可被实现为宏,故参数不应当是具有副作用的表达式;返回值是int,因为常量EOF是-1int fgetc(FILE *fp); // 一定是个函数

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航