unix环境高级编程-标准IO
标准IO库:
不仅在unix上,在很多操作系统上都实现了标准的IO库,它处理了很多细节,例如缓冲区分配,优化长度执行IO等。
流和FILE对象:
对于标准的IO库,它们的操作是围绕流(stream)进行的。当用标准IO库打开或创建一个文件时,已经使一个流和一个文件相关联,标准的io文件流可用于单字节和多字节字符集,流的定向决定了所读。所写的字符是单字节还是多字节的,当一个流最初被创建,并没有定向,若在一个未定向的流上使用一个多字节IO函数,则将该流的定向设置为宽定向,若在未定向的流上使用单字节IO函数,则流定向为字节定向的。只有两个函数能够改变流的定向,freopen清除一个流的定向,fwide函数设置流的定向。
当打开一个流时,标准IO函数fopen返回一个指向FILE对象的指针,该对象通常是一个结构,包含了标准IO库为管理该流需要的所有信息,包括用于实际IO文件描述符、指向用于该缓冲区的指针、缓冲区的长度、当前在缓冲区的字符数等。
应用程序没有必要检验FILE对象,为了引用一个流,需将FILE指针作为参数传递给每个标准IO函数,称指向FILE对象的指针为文件指针。
标准输入,标准输出和标准出错:
对一个进程预定义了三个流,可以自动被进程使用,,这三个标准io流通过预定义文件指针stdin,stdout和stderr加以引用,这三个指针同样定义在头文件<stdio.h>中。
缓冲:
标准io库提供缓冲的目的是尽可能减少使用read和write调用的次数,对io流自动进行缓冲管理。
标准io提供三种类型的缓冲:
1.全缓冲,这种情况下,填满io缓冲区才能进行实际io操作,在一个流上进行第一次io操作,相关标准io函数通常调用malloc获取缓冲区
2.行缓冲,当输入和输出遇到换行符,执行io操作,当流涉及到一个终端时,通常使用行缓冲。
3.不带缓冲,标准库不对字符进行缓冲存储
标准出错是不带缓冲的,打开至终端设备的是行缓冲的,其他流是全缓冲的。
更改缓冲类型:
这些函数一定要在流已被打开的后调用,setbuf函数打开或关闭缓冲机制,使用setvbuf,可以精确的指定所需的缓冲类型,这是用mode参数实现的
_IOFBF
_IOLBF
_IONBF
下表是两个函数的参数和动作:
任何时候都可以强制冲洗一个流:
此函数可以使得该流所有未写的数据都被传送至内核,作为一种特殊情形,如果fp是null,则该函数将导致所有输出被冲洗。
打开流:
三个函数可打开一个标准io流
三个函数的区别
1.fopen打开一个指定文件
2.freopen在一个指定的流上打开一个指定的文件,该函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出或标准出错
3 fdopen 获取一个现有的文件描述符,并使一个标准的io流与该描述符相结合,此函数常用于由创建管道和网络通信通道函数返回的描述符,因为这些特殊类型文件不能用标准io fopen函数打开,所以必须先调用设备专用函数以获得一个文件描述符,然后用fdopen使一个标准io流与该描述符相关联。
type参数指定对该IO流的读写方式,规定type有15种不同的值,如下表
对应上表,下表列出了打开一个流的6种不同的方式:
调用flcose关闭一个打开的流
在文件被关闭之前,冲洗缓冲中的输出数据,缓冲区的任何输入数据被丢弃,如果标准IO库已经为该流自动分配了一个缓冲区,则释放该缓冲区。
当一个进程正常终止时,则所有带有未写缓冲数据的标准IO流都被冲洗,所有打开的标准IO流都被关闭。
读和写流:
一旦打开了流,可在三种不同类型的非格式化io中进行选择。
1.每次一个字符的io,一次读或写一个字符,如果流是带缓冲的,则标准io会处理所有缓冲。
2.每次一行的io,想要一次读或写一行,则使用fgets和fputs,每行以换行符终止,
3.直接io,fread和fwrite函数支持这种类型的io,这两个函数常用于从二进制文件中每次读或写一个结构。
输入函数:以下三个函数,可用于一次读一个字符
输出函数:对应这三个输入函数
每次一行io:
两个函数都指定了缓冲区地址,读入的行将送入其中,gets从标准输入读,fgets从指定流读。
对于fgets,必须指定缓冲区的长度n,此函数一直读到下一个换行符为止,但是不超过n-1个字符,读入送入缓冲区,缓冲区以null字符结尾。
gets不推荐使用,因为不能指定缓冲区的长度,容易溢出。
二进制io:
更愿意一次读或写整个结构,必须循环通过整个结构,提供两个函数进行io操作:
这两个函数有两种常见用法:
1. 读或写一个二进制数组
2.读或写一个结构
这两个函数返回读或写的对象数,对于读,如果出错或到达文件尾端,则此数字可以少于nobj,在这种情况,应该调用ferror或feof以判断究竟是哪种情况,对于写,如果返回值少于要求的nobj,则出错。
定位流:
有三种方法定位标准io流:
1. ftell和fseek函数
2.ftello和fseeko函数
3.fgetpos和fsetpos函数
格式化io(printf scanf):
格式化输出:
printf将格式化数据写到标准输出,fprintf写到指定的流,dprintf输出到指定文件描述符,sprintf将格式化的字符送入数组buf中。
格式化输入:
三个scanf函数
scanf族用于分析输入字符串,并将字符串序列转换成指定类型的变量。
临时文件:标准IO库提供了两个函数以帮助创建临时文件
内存流:
标准io库把数据缓存在内存中,因此每次一字符和每次一行的io更有效。也可以通过调用setbuf或setvbuf函数让io库使用自己的缓冲区
三个函数可用于内存流的创建,第一个是fmemopen函数
#include <stdio.h>
FIFE *fmemopen(void *restrict buf, size_t size, const char *restrict type);
允许调用者提供缓冲区用于内存流,buf参数指向缓存区开始位置,size参数指定了缓冲区大小的字节数。
其他两个函数分别是,open_memstream和open_wmemstream
posted on 2016-07-26 21:52 sichenzhao 阅读(130) 评论(0) 编辑 收藏 举报