unix环境高级编程-5.4-缓冲

提到缓冲这个概念,大家都知道非常熟悉不过了,我们在写程序的时候,比如java,C++都会涉及到一些缓冲的概念,那么到底缓冲有什么好的作用的。

其实缓冲在unix的操作系统里,就是为了减少read和write的调用次数。在第三章中,对不同缓冲区的长度设置,执行IO所要的cpu时间量是不一样的。他也对每个io流自动的进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。不幸的是,标准I/O库最令人迷惑的也是他的缓冲。

标准I/O缓冲提供了三种类型的:

(1)全缓冲。这种情况下,是在填满了标准的IO缓冲区后才进行实际的I/O操作。对于驻留在磁盘上的文件通常都是标准I/O库实施全缓冲的。在一个流上执行第一次I/O操作时候,相关标准I/O函数通常调用malloc获得需要使用的缓冲区。

术语冲洗(flush)说明标准I/O缓冲区的写操作,缓冲区可由标准IO例程自动冲洗,或者可以调用函数fflush冲洗一个流。值得注意的是,在unix环境中,flush有两个含义,标准I/O函数库中,flush冲洗意味着将缓冲去的中的内容邪道磁盘上。在终端驱动程序方面,flush表示丢弃已经存储在缓冲去的中的数据。

(2)行缓冲。在这种情况下,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。允许我们一次输出一个字符,(用标准I/Ofputc函数),但只有在写了一行之后才进行实际的IO操作。当涉及一个终端的时候,通常使用行缓冲。

对于行缓冲有两个限制,第一,因为标准io库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲去,那么即使还没有写一个换行符,也进行IO操作,第二,任何时候只要通过标准的IO库要求从从(a)一个不带缓冲的流,或者(b)一个行缓冲的流,得到输入数据,那么就会造成冲洗所有行缓冲输出流。在(b)中袋了一个在括号忠的说明其理由是,所要的数据可能已在该缓冲区忠,它并不要球在需要数据时候猜中内核中读数据。很明显,从不带缓冲的一个流中进行输入。,要求当时从内核得到数据。

(3)不带缓冲。标准I/O库中不对字符进行缓冲存储。例如,如果用标准的I/O函数fputs的写15个字符到不带缓冲的流中,则该函数很可能用3.8节的write系统调用函数将这些字符理解写在相关连的打开的文件中。

标准出错流是通常是不带缓冲的。这就使得出错信息可以尽快的显示出来。而不管他们是否含有一个换行符。

IOS C要求下列缓冲特征;

  • 当且仅当标准舒服和标准输出并不涉及互式设备的时候,他们才是全缓冲。
  • 标准出错绝不会全是缓冲的。

系统默认的

  • 标准出错是不带缓冲的。
  • 如果是涉及终端设备的其他流的时候,则他们是行缓冲的。否则是全缓冲。

对于任何一个给定的流,如果我们不喜欢这些系统默认的情况,则可调用下列的两个函数, 的任何一个更改类型

#include<stdio.h>
void setbuf(FILE* restrict fp,char* restrict buf);

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

\如成功则返回零,出错返回非0值。

查看GNU c手册。

void setbuf (FILE *stream, char *buf) [Function]
If buf is a null pointer, the effect of this function is equivalent to calling setvbuf
with a mode argument of _IONBF. Otherwise, it is equivalent to calling setvbuf with
buf, and a mode of _IOFBF and a size argument of BUFSIZ.
The setbuf function is provided for compatibility with old code; use setvbuf in all
new programs.
void setbuffer (FILE *stream, char *buf, size t size) [Function]
If buf is a null pointer, this function makes stream unbuffered. Otherwise, it makes
stream fully buffered using buf as the buffer. The size argument specifies the length
of buf.
This function is provided for compatibility with old BSD code. Use setvbuf instead.

void setbuf (FILE *stream, char *buf) [Function]
If buf is a null pointer, the effect of this function is equivalent to calling setvbuf
with a mode argument of _IONBF. Otherwise, it is equivalent to calling setvbuf with
buf, and a mode of _IOFBF and a size argument of BUFSIZ.
The setbuf function is provided for compatibility with old code; use setvbuf in all
new programs.
void setbuffer (FILE *stream, char *buf, size t size) [Function]
If buf is a null pointer, this function makes stream unbuffered. Otherwise, it makes
stream fully buffered using buf as the buffer. The size argument specifies the length
of buf.
This function is provided for compatibility with old BSD code. Use setvbuf instead.

这个函数一定要在流已经在被打开后调用,(十分明显,因为每个函数都要求一个有效的文件指针作为他的一个参数),而且应该要在对该流执行任何一个其他操作之前调用。

可以使用setbuf函数打开或者关闭缓冲机制。为了嗲缓冲进行I/O,参数buf必须指向一个长度为为BUFSIZE,的缓冲区,该常量定义在<stdio.h>,通常再次之后该流就是全缓冲的。但是如果,该流与一个终端蛇鞭先关,那么某些系统也可以间隙其设置为航缓冲。为了关闭缓冲,必须将buf设置为MULL.

s使用setvbuf,我们可以景区的指定所需的缓冲类型。这是用mode参数实现的。

_IOFBF 全缓冲

_IOLBF 行缓冲

_IONBF 不带缓冲

如果,指定一个不带缓冲的流,则忽略buf和size参数,如果只的那个全缓冲和行缓冲,则buf和size可选择指定的一个缓冲区及其长度。如果该流是带缓冲的。而buf是努力啦,则标准的库,将自动的诶该流分配适当的长度的缓冲区。适当长度的指的是有常量BUFSIE所指定的值。

下图:

要了解,如果在一个函数内分配一个自动变量类的标准I/O缓冲区,则从该函数返回之前,必须关闭该流。另外有些实现将缓冲区的一部分用于村饭他自己的管理操作信息,所以可以存放换从去忠的实际数据字节数少女size。一般

一般而言,应该有系统选择缓冲区的长度。并自动分配。

任何时候我们可以强制刷新一个流。

#include<stdio.h>

int fflush(FILE * fp);


成功返回0,出错则会EOF.

int fflush (FILE *stream) [Function]
This function causes any buffered output on stream to be delivered to the file. If
stream is a null pointer, then fflush causes buffered output on all open output
streams to be flushed.
This function returns EOF if a write error occurs, or zero otherwise.

此函数使该流所有威胁的数据被传送值内核,作为一个特例,如若fp是NULL,此函数将倒是所有输出流被冲洗。

更多请访问:http://blog.csdn.net/wallwind