APUE(5)---标准I/O库 (1)
一、引言
标准I/O库不仅是UNIX,许多i其他操作系统都实现了标准I/O库,所以这个库由ISO C标准说明。标准I/O库处理很多细节,如缓冲区分配,以及优化的块长度执行I/O等。这使得它便于用户使用,但是如果我们不能深入了解I/O库函数的操作,也会带来一些问题。
二、流和FILE对象
第三章中所有I/O函数都是围绕文件描述符的。当打开一个文件是,即返回一个文件描述符,然后该文件描述符就用于后续的I/O操作。而对于标准I/O库,它们的操作是围绕流(stream)进行的,当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联。标准I/O文件刘可用于单字节或款字节字符集。流的定向(stream‘s orientation)决定了所读、写的字符是单字节还是多字节的。只有两个函数可改变流的定向。freopen函数清除一个流的定向,fwide函数可用于设置流的定向。
#include <stdio.h>
#include <wchar.h>
int fuidw(FILE *fp, int mode);
//若流是款定向的,返回正值,若流是字节定向的,返回负值;若流是未定向的,返回0
mode参数为正值,fwide将试图使指定的流是宽定向的;mode参数为负值,将试图使指定的流是字节定向的;当mode为0,不做定向,返回标识流的定向值。需要注意两点:fwide并不改变已定向流的定向;fwide无出错返回。
三、标注输入、标准输出和标准错误
对一个进程预定义了3个流,他们可以自动地被进程使用,他们是:标注输入、标注输出和标准错误。这些流与第三章提到的文件描述符STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO所引用相同。这三个标准I/O流通过预定义文件指针stdin、stdout和stderr加以引用。这三个文件指针定义在头文件<stdio.h>中。
四、缓冲
标准I/O库提供缓冲的目的是进了能减少使用read和write调用的次数。他也对每个I/O流自动地进行缓冲管理。标准I/O库提供三种类型的缓冲:
1、全缓冲:这种情况下,在填满标准I/O缓冲区才进行实际I/O操作;对于驻留在磁盘上的文件通常是由标准I/O库事实全缓冲的。
2、行缓冲:在这种情况下,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作;当流涉及到终端时,通常使用行缓冲。对于行缓冲有两个限制。第一,因为标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使还没有写一个换行符,也进行I/O操作;第二,任何时候只要通过标准I/O库从(a)一个不带缓冲的流,或者(b)一个航缓冲的流(它从内核请求需要数据,其请求的数据可能已在缓冲区)得到输入数据,那么就会冲洗所有行缓冲输出流。
3、不带缓冲:标准I/O库不对字符进行缓冲;标准错误流stderr通常是不带缓冲的,这就是的出错信息可以尽快显示出来,而不管他们是否含有一个换行符。
ISO C要求下列缓冲特征:当且仅当标准输入和标准输出并不指向交互式设备时,他们才是全缓冲的;标准错误决不会是全缓冲的。大多数系统默认的是:标准错误是不带缓冲的;指向终端设备的流,则是行缓冲的,否则是全缓冲的。
对于任何一个给定的流,如果我们并不喜欢这些系统默认,则可调用下列两个函数中的一个更改缓冲类型:
#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf);
void setvbuf(FILE *restrict fp, cahr *restrict buf, int mode, size_t size);
setbuf函数可以打开或关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ的缓冲区,通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可将其设置为行缓冲的;为了关闭缓冲,将buf设置为NULL。
setvbuf函数可以精确地说明所需的缓冲类型。这些用mode参数实现:_IOFBF、_IOLBF、_IONBF,如果指定一个不带缓冲的流,则忽略buf和size参数;如果指定全缓冲或行缓冲,则buf和size可选择地指定一个缓冲区及长度。如果该流是带缓冲的,而buf是NULL,则标准I/O库将自动地为该流分配适当长度的缓冲区。如果在一个函数内分配一个自动变量类的标准I/O缓冲区。则从该函数返回之前,必须关闭该流。一般情况都应由系统选择缓冲区的长度并自动分配缓冲区,在这种情况下,标准I/O库自动释放缓冲区。
术语冲洗(flush)说明标准I/O缓冲区的写操作。缓冲区可由标准I/O例程自动地冲洗,或者可以调用函数fflush冲洗一个流。flush有两层意思:在标准I/O库方面,flush意味着将缓冲区中的内容写到磁盘上;在终端驱动程序方面,flush标识丢弃已存储在缓冲区的数据。
#include <stdio.h>
int fflush(FILE *fp);
次函数是该流所有威胁的数据都被传送至内核。作为一种特殊情形,如若fp是NULL,则次函数将导致所有输出流被冲洗。
五、打开流
#incldue <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流,区别是:fopen打开一个流;freopen在一个指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流。如该流已经定向,则使用freopen清除该定向。次函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出和标准错误;fdopen函数娶一个已有的文件描述符,并使一个标准的I/O流与该描述符相结合。
type参数指定对该I/O流的读、写方式,ISO C规定参数可以有15中不同的值(r/w/a/r+/w+/a+)。需要注意的是标准I/O库是可以区分文本文件和二进制文件,因为UNIX内核并不对这两种文件进行区分,所以在UNIX系统环境下指定字符b作为type的一部分实际上并无作用。
当以读和写类型打开一个文件时,具有如下限制:如果中间没有fflush、fseek、fsetops或rewind,则在输出的后面不能直接跟随写入;如果中间没有fseek、fsetops或rewind,或者一个输入操作没有达到文件尾端,则在输入操作之后不能跟随输出。
除非流引用终端设备,否则按系统默认,该流被打开时是全缓冲的。若流引用终端设备,则该流是行缓冲的。一旦打开了流,那么在对该流执行任何操作之前,如果希望,则可使用setbuf和servbuf改变缓冲的类型。
#include <stdio.h>
int fclose(FILE *fp);
在该文件被关闭之前,冲洗缓冲中的输出数据,缓冲区中的任何输入数据被丢弃,如果标准I/O库已经为该流自动分配了一个缓冲区,则释放该缓冲区。当一个进程正常终止时,则所有带威胁缓冲数据的标准I/O流都被冲洗,所有打开的标准I/O流都被关闭。
APUE(5)---标准I/O库 (1)的更多相关文章
- [05]APUE:标准 I/O 库
[a] setvbuf / setbuf #include <stdio.h> int setvbuf(FILE *restrict fp, char *restrict buf, int ...
- APUE(5)---标准I/O库 (3)
十.定位流 #include <stdio.h> long ftell(FILE *fp); //若成功,返回当前文件位置指示:若出错,返回-1L int fseek(FILE *fp, ...
- APUE(5)---标准I/O库 (2)
六.读和写流 一旦打开了流,则可在3种不同类型的非格式化I/O中进行选择,对其进行读.写操作:1)每次一个字符的I/O,一次读或写一个字符,如果刘时代缓冲的,则标准I/O函数处理所有缓冲:2)每次一行 ...
- APUE 学习笔记(四) 标准I/O库
1.流与FILE对象 unix I/O系统调用都是针对文件描述符的 标准C的I/O函数都是针对流(文件指针)的,我们使用一个流与一个文件相关联 2.缓冲 标准I/O库提供缓冲的目的就是尽可能减少r ...
- APUE之第5章——标准I/O库
一.知识回顾:文件I/O 文件 I/O 是不带缓冲的 I/O(unbuffered I/O),指每个 read 和 write 都调用内核中的一个系统调用. 对于内核而言,所有打开的文件都通过文件描述 ...
- 《UNIX环境高级编程》(APUE) 笔记第五章 - 标准I/O库
5 - 标准I/O库 Github 地址 1. 标准 I/O 库作用 缓冲区分配 以优化的块长度执行 I/O 等 使用户不必担心如何选择使用正确的块长度 标准 I/O 最终都要调用第三章中的 I/O ...
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- 标准I/O库之临时文件
ISO C标准I/O库提供了两个函数以帮助创建临时文件. #include <stdio.h> char *tmpnam( char *ptr ); 返回值:指向唯一路径名的指针 FILE ...
- 标准I/O库之标准I/O的效率
程序清单5-1 用getc和putc将标准输入复制到标准输出 #include "apue.h" int main( void ) { int c; while(( c = get ...
随机推荐
- 基于RabbitMQ的跨平台RPC框架
RabbitMQRpc protocobuf RabbitMQ 实现RPC https://www.cnblogs.com/LiangSW/p/6216537.html 基于RabbitMQ的RPC ...
- 2019 最新 阿里天猫、蚂蚁、钉钉ava 面试题汇总,附答案
Java面试前需要做足各方面的准备工作,肯定都会浏览大量的面试题,本人也不例外,这是一些最新面试题,分享给大家. Java基础 面向对象的特征:继承.封装和多态 int 和 Integer 有什么区别 ...
- ubuntu下安装stm32开发环境
在windowns下开发stm32刚开始学最烦的就是创建工程模板,都不知道为什么要那样设置,而且步骤繁多.现在我告诉大家一个好消息,在linux下配置stm32开发环境包括创建工程,使用JLink仿真 ...
- IIS7.5 URL文件名有加号或空格显示404错误的解决办法
转:http://www.gyd.cc/zhuanti/tech/9319.html 将服务器由windows2003升级到windows2008后,某个网站的图片突然不能显示,显示404错误, 后来 ...
- 转载----我与CMDB不得不说的故事
每次读到配置管理相关的书籍时,我总在想:“这些定义很精准,流程也很完整,但这不是真正的难题.”对于一个配置管理者来说,真正的难题不是绘制“庞大而精美”的数据模型,不是设计“全天候.无死角”的管控流程, ...
- MySQL 索引优化原则
一.索引优化原则 1.最左前缀匹配原则,联合索引,mysql会从做向右匹配直到遇到范围查询(>.<.between.like)就停止匹配,比如a = 1 and b = 2 and c & ...
- Android真机调试手动添加程序包的LogCat
android真机调试有时候看LogCat 时,有时候那个跑的本程序的LogCat 没有出现而是 出现的是" All messages (no filters) " .此时 的Lo ...
- python操作符重载
操作符重载的魔术方法 操作符 方法 取反 即席 + __add__ __radd__ __iadd__ - __sub__ __rsub__ __isub__ * __mul__ __rmul__ _ ...
- 简述 ascii、unicode、utf-8、gbk 的关系 (全网最全!!!)
ascii 是最早美国用的标准信息交换码,把所有的字母的大小写,各种符号用 二进制来表示,共有256中,加入些拉丁文等字符,1bytes代表一个字符, Unicode是为了统一世界各国语言的不用,统一 ...
- iOS判断字母、数字串
以下为NSString类的扩展方法,分别是判断字符串是否只是包含字母.是否只包含数字.是否只包含字母和数字: //字母 - (BOOL)cdm_isOnlyLetters { NSCharacterS ...