标准IO库--unix环境高级编程读书笔记

来源:互联网 发布:如何找到一元包邮 淘宝 编辑:程序博客网 时间:2024/05/22 00:16

     标准IO库是C语言提供的一个库,不光存在于linux中,在windows中也是有的。标准IO库和文件IO的不同是,标准IO库是对文件IO(即系统调用)的封装,并且在用户层添加了一些缓冲区。

    文件IO的所有操作都是针对文件描述符进行的,而标准IO则使用文件指针。当打开或创建一个文件时,标准IO使得文件与一个流相结合。例如,用fopen打开一个文件,则返回一个FILE结构体的指针,所有的操作都是通过FILE指针进行的。FILE结构体中包含了文件的描述符,缓冲区的长度,指向缓冲区的指针以及文件的出错标记等。

    在文件IO一章中,说明了标准输入输出对应的三个文件的文件描述符分别是STDIN_FILENOSTDOUT_FILENO以及STDERR_FILENO,它们对应的文件指针分别是stdinstdoutstderr

    标准IO的缓存可以分为一下三种:

 全缓存:在全缓存的情况下,只有当在用户区的缓存装满或者调用fflush函数时,才会将缓存中的内容写入到内核,在通过内核写入到文件中去。 行缓存:在行缓存的情况下,只有当遇到一个换行符时,才会进行IO操作。 不缓存:就是没有缓存。

全缓存一般用于非交互式的文件存取中,例如读一个制定的文本文件一般采用全缓存的方式。行缓存常用于终端的交互。例如,标准输入和标准输出就采用行缓存。不缓存的情况就是标准出错了,在这中情况下,要求将出错信息尽快的输出,当然不能使用缓存了。

    可以使用setbufsetvbuf来设置一个流的缓存,它们的函数原型如下:

     int setbuf(FILE* fp,char* buf);     int setvbuf(FILE* fp,char* buf,int mode,size_t size);

如果函数执行成功返回0,否则返回非0setbuf第一个参数为文件指针,第二个参数buf必须指向一个长度为BUFSIZ的缓冲区,BUFSIZstdio.h头文件中定义。如果bufNULL,则为不带缓存。setvbuf第一个参数为文件指针,第二个参数为缓冲区的指针,第三个参数指定缓存的方式,第四个参数指定缓存的长度。mode可选择的有一下类型:

_IOFBF全缓存_IOLBF行缓存_IONBF无缓存

如果该流是带缓存的,即mode的值不是_IONBF,但是buf的值为NULL,则系统自动为该流分配缓存。如果mode_IONBF,则忽略bufsize的值。设置缓存的工作一定要在流还没有进行任何的操作之前进行,否则第一次对刘德操作将导致缓存的自动分配。一般来说,缓存的分配应该有系统自动进行,这样就可以在关闭流的时候,自动释放分配的缓存。

我们可以使用fflush强制刷新一个缓存,它的函数原型如下:

  int fflush(FILE* fp);

    linux中,刷新有两个意思,

1)强制将缓存中的数据写入到磁盘上,即使缓存没有写满

2)强制将缓存中的数据丢弃

在这里fflush当然是第一种操作。

    打开流的操作有三个函数:

FILE* fopen(const char* filename,const char* type);FILE* freopen(const char* pathname,const char* type,FILE* fp);FILE* fdopen(int filedes,const char* type);

如果函数执行成功,则返回文件指针,否则返回空指针NULLtype用来指定文件的打开方式,它的选择有r,w,a,rb,wb,ab,r+,w+,a+。第二个函数是在一个特定的流上打开一个文件,如果该流已经打开,则先将该流关闭。此函数一般用于将指定的文件打开为一个预定义的流,如标准输入,标准输出和标准出错。在使用fopen函数创建一个文件时,没有办法指定新建文件的权限。在linux系统中规定,新建的文件的权限为S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH

    使用fclose函数关闭一个流,它的函数原型如下:intfclose(FILE*fp);当关闭一个流时,会自动刷新输出缓存中的数据,丢弃输入缓存中的数据。如果缓存是自动分配的,则会自动释放缓存。

    一次从文件中读取一个字符的函数有getcfgetcgetchargetcfgetc的功能是相同的,只不过getc是用宏来实现的,fgetc使用函数来实现的。所以说,getc的效率要比fgetc的效率高一些。而个getchar直接是从标准输入读取字符的。这三个函数的函数原型如下:

int getc(FILE* fp);int fgetc(FILE* fp);int getchar(void);

与之对应的三个输出函数分别是:

int putc(int c,FILE* fp);int fputc(int c,FILE* fp);int putchar(int c);

putchar直接输出到标准输出。ungetc可以将读出的字符重新送回到流中:

int ungetc(int c,FILE* fp);

    可以使用ferrorfeof来检测在操作流的过程中是碰到了文件的末尾,还是发生了错误。可以使用clearerr函数来清除FILE中的erroreof标志。

    每次输入一行的IO操作有,getsfgets,它们的函数原型如下:

char* gets(char* buf);char* fgets(char* buf,int n,FILE* fp);

gets函数直接从标准输入接收字符串,缓冲区buf的长度由stdio.h文件中的BUFFSIZ指定,用户不能指定缓冲区的大小。所以,当输入的字符足够长,就会越出buf的缓冲区,从而造成不可预测的后果,这个漏洞就曾经被人利用,造成1988年的因特网蠕虫病毒事件。所以gets函数是不建议使用的。与这两个函数相对应的输出函数是putsfputs

int puts(const char* str);int fputs(const char* str,FILE* fp);

puts将指定的字符串输出到标准输出,并且输出一个换行符。freadfwrite函数用来对二进制文件进行操作,它一般用来向文件中写入(或从文件中读出)若干数目的结构体。

    对流的定位可以使用ftellfseek以及fgetposfsetpos。格式化输出函数有三个:printffprintfsprintf,对应的格式化输入函数有scanffscanf以及sscanf。在标准io库中提供了两个用于创建临时文件的函数tmpnamtmpfile


0 0
原创粉丝点击