现在的位置: 首页 > 综合 > 正文

[UNIX环境高级编程第二版]读书笔记5章

2013年08月12日 ⁄ 综合 ⁄ 共 3333字 ⁄ 字号 评论关闭

5.1  标准I/O由Dennis Ritchie在1975年左右编写。
5.2  第三章的I/O都是针对文件描述符。而标准I/O库是围绕stream,打开或创建文件时,我们已经使一个stream与文件相关联。
     stream的定向决定了读写的字符是单字符还是多字节。在未定向的流上使用I/O函数可以改变定向。只有两个函数可以改变流定向。freopen用来清除stream的定向。
     int fwide(FILE *fp, int mode); mode 负数 试图指定字节定向。 正值,试图指定宽定向。   0,不设置,返回当前的定向值。
5.3  文件描述符STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO分别和stdin,stdout,stderr引用的文件是相同的。
     前者#include <unistd.h>中,后缀定义在#include <stdio.h>中。
5.4  标准I/O提供缓冲的目的是减少读写的调用次数。
     1)全缓冲。填满标准I/O缓冲区才进行实际I/O操作。常见的是磁盘上的文件。可以调用fflush(写入),tcflush(丢弃)现有缓冲内容。
     2)行缓冲。输入和输出中遇到换行符时,标准I/O库执行I/O操作。a>长度固定,满了就I/O操作。b>标准I/O库要求从“不带缓冲”或“带行缓冲”的流中得到输入数据,则会执行。
     3)不带缓冲。标准I/O库不对字符进行缓冲存储。如fputs函数。标准stderr通常不带缓冲。
     ISO C要求下列缓冲特征:
     #当且仅当stdin和stdout不涉及交互device,才是full缓冲。
     #stderr绝不是full缓冲。
     很多默认系统:
     #stderr不是带缓冲的。
     #涉及到terminal设备的其他stream,是line缓冲。否则是full缓冲。

     void setbuf(FILE *restrict fp, char *restrict buf);打开或关闭缓冲机制。
     int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
     int fflush(FILE *fp);强制flush一个steam,该流所有未write的数据都被传送至内核。如果fp为NULL,则所有输出流被flush。
     详细情况看下图
     
5.5  打开一个标准流。
     FILE *fopen(const char *restrict pathname, const char *restrict type);打开指定流。
     FILE *freopen(const char *restrict pathname, const char* restrict type, FILE *restrict fp);
     在指定流打开指定文件。如流已打开,则先关闭。如已定向,则清除定向。一般用于将指定文件打开为stdin,stdout或stderr。
     FILE *fdopen(int filedes, const char *type);使标准I/O流与文件描述符相结合。filedes通常是创建“管道”和“网络通信通道”函数的返回值。(POSIX.1专有)
     打开模式见下图
     
     int fclose(FILE *fp);关闭打开的流。关闭前,会flush缓冲区中的output数据。丢弃任何input数据。
5.6  一旦打开流,可以在三种不同type的非格式化I/O中进行选择,对其read,write。
     1)每次一个字符I/O。
        输入:int getc(FILE *fp);
              int fgetc(FILE *fp);
              int getchar(void);等价于getc(stdin)。
           不管是出错还是EOF,三个函数返回同样的值,为了区分。比如调用:
              int ferror(FILE *fp);
              int feof(FILE *fp);
              void clearerr(FILE *fp);大多数实现中,每个流在FILE对象中维持了a)出错标志。b)eof标志。此函数可以清除这两个标志。
              int ungetc(int c, FILE *fp);从流中读取数据后,可以调用此函数将字符再压送回流中。
        输出:int putc(int c, FILE *fp);
              int fputc(int c, FILE *fp);
              int putchar(int c);等价于putc(c, stdout)。
     2)每次一行的I/O。fgets,fputs
     3)直接I/O。fread,fwrite。
5.7  每次一行I/O。
     输入:char *fgets(char *restrict buf, int n, FILE *restrict fp);从流中读取n-1个字符。
           char *gets(char *buf);从stdin中读取,不会讲换行符存入缓冲区,不推荐使用。
     输出:int fputs(const char *restrict str, FILE *restrict fp);将null结尾的字符串写到指定流。结尾的null不写出。不一定每次输出一行,遇到null就停止。
           int puts(const char *str);将null结尾的写到stdout,null不写。但是puts由将一个换行符写到stdout。不推荐使用。
5.8  标准I/O库与直接调用read,write函数相比并不慢多少。
5.9  size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
     size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
     常见的用法:1)读或写一个二进制数组。比如:
                 float data[10];    fwrite(&data[2], sizeof(float), 4, fp);写2-5元素到文件上。
                 2)读或写一个结构。
5.10 定位流有三种方法。
     1)ftell和fseek。都假定文件的位置可以存放在一个long中。
     2)ftello和fseeko。Single UNIX Specification引入的。使用off_t代替了long。
     3)fgetpos和fsetpos。由ISO C引入。使用抽象数据类型fpos_t记录文件位置。
5.11 格式化输出
     printf, fprintf, sprintf, snprintf.
     vprintf, vfprintf, vsprintf, vsnprintf.可变参数。
     格式化输入
     scanf, fscanf, sscanf.
5.12 对于stream可以用int fileno(FILE *fp);来获取其文件描述符。
     fp->_IO_file_flags &_IO_UNBUFFERED等等。如有buffer,大小为fp->_IO_buf_end - fp->_IO_buf_base;
5.13 创建临时文件。
     char *tmpnam(char *ptr);最多调用次数TMP_MAX。
     FILE *tmpfile(void);创建临时二进制文件(类型wb+),关闭文件或程序结束自动被删除。
     char *tempnam(const char *directory, const char *prefix);XSI扩展,非ISO C。
     int mkstemp(char *template);XSI扩展,非ISO C。
5.14 标准I/O效率不高。可以替代它的版本有sfio(Korn & Vo[1991])。Krieger,Stunmm & Unrau[1992]使用映射文件--mmap函数。
     许多标准I/O库实现可用于C函数库中。两种实现是uClibc C库,以及newlibc库。
5.15 大多数UNIX应用程序都使用标准I/O库。
     

【上篇】
【下篇】

抱歉!评论已关闭.