您的位置:首页 > 产品设计 > UI/UE

读书笔记-APUE第三版-(5)标准IO库

2014-05-04 21:24 295 查看
ISO C标准I/O库使用流的概念读写文件。流是对数据传输的抽象,可以把流理解为从起点到终点间的字节序列。

标准I/O库通过维护进程空间内的缓冲区,减少read/write系统调用次数来提高I/O效率。之前介绍的Unbuffered I/O和文件描述符fd打交道,标准I/O则使用FILE指针。

typedef struct{
short level;/*缓冲区满程度*/
unsigned flags;/*文件打开状态标志*/
char fd;/*文件描述符*/
unsigned char hold;/*若无缓冲区不读取*/
short bsize; /*缓冲区大小*/
unsigned char *buffer; /*缓冲区位置*/
unsigned ar *curp; /*当前读写位置*/
unsigned istemp; /*临时文件指示*/
short token; /*用作无效检测*/
}FILE;


缓冲区

在打开文件时,标准I/O库负责自动分配缓冲区,还可以通过setbuf/setvbuf函数显式设置缓冲区类型、大小甚至关闭缓冲区。

Fully buffered(全缓冲):通常情况下,硬盘上的文件读写操作都使用全缓冲,当缓冲区满的时候才触发flush操作。
Line buffered(行缓冲):行缓冲一般用于终端下的标准输入/输出操作,遇到换行符或者缓冲区满时都会发生I/O操作。(注:当标准I/O库不使用缓冲或者使用行缓冲需要从内核读取数据时,行输出缓冲会被flush)。
Unbuffered(不缓冲):标准错误输出不使用缓冲。

打开/关闭文件

打开文件:FILE *fopen(const char *restrict pathname, const char *restricttype);打开类型如下:


三个预定义的文件流指针被自动打开,分别是stdin标准输入、stdout标准输出和stderr标准错误流。
关闭文件:int fclose(FILE *fp);所有缓冲输出数据被flush,缓冲输入数据被丢弃。进程正常退出时,所有文件流被自动关闭

读写操作

字符读写

#include"apue.h"
int main(void)
{
int c;
while ((c = getc(stdin)) != EOF)
if (putc(c, stdout) == EOF)
err_sys("output error");
if (ferror(stdin))
err_sys("input error");
exit(0);
}


读取函数包括getc(通常为宏)/fgetc(不能是宏,只能是函数)/getchar(从标准输入流读取),它们都返回int整数,从unsignedchar转换而来,这样正常返回值都是正数,可以和EOF(典型值为-1)区分出来。

行读写

#include"apue.h"
int main(void)
{
char buf[MAXLINE];
while (fgets(buf, MAXLINE, stdin) != NULL)
if (fputs(buf, stdout) == EOF)
err_sys("output error");
if (ferror(stdin))
err_sys("input error");
exit(0);
}


使用fgets/gets/fputs/puts要注意以下问题:缓冲区溢出,是否自动添加\0和\n等。

二进制读写

fread和fwrite函数用于读写二进制数据。要注意的是,由于字节对齐、字节顺序、编译器、计算机体系结构差异,二进制读写兼容性比较差。

struct {
short count;
long total;
char name[NAMESIZE];
} item;
if(fwrite(&item, sizeof(item), 1, fp) != 1)
err_sys("fwrite error");


效率对比



标准I/O的User CPU时间较高,因为相比第一行read/write操作BufferSize使用4096 ,标准I/O的while循环次数要多得多。
标准I/O的System CPU时间接近最优化状态,可见标准I/O会使用合适的缓冲区大小。
最后一行每读写一个字节都进行系统调用,所以性能最差

其他重要函数

文件流定位:ftell(返回long)/ftello(返回off_t)/fseek/fseeko/rewind/fgetpos/fsetpos,后两个是ISO C标准中定义的,可以在非UNIX系统中使用
格式化:printf家族:printf(标准输出)/fprintf(输出到文件)/sprintf(输出到字符数组缓冲区)/snprintf(指定缓冲区大小避免溢出)。相对应的是scanf家族。
临时文件:tmpnam(返回唯一路径)/tmpfile(创建临时文件,关闭后被自动删除)/mkdtemp/mkstemp(能指定临时文件名模板)。
内存流:fmemopen,把某段内存当做FILE流返回,然后进行I/O操作,一般用于创建字符串
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  apue unix 操作系统