FILE I/O

     ANSI C里定义的标准I/O是一种带缓冲的高级磁盘I/O,目的是尽可能减少使用read和write系统调用的次数,从而提高I/O效率。标准I/O提供了3种类型的缓冲类型。

1. 全缓冲(Full buffering)。在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。对驻留在磁盘上的文件的访问通常是由标准I/O库实施全缓冲的。


2.行缓冲。在这种情况下,当在输入和输出中遇到新行符时,标准I/O库执行I/O操作,这允许我们一次输出一个字符(如fputc函数),但只有写了一行之后才进行实际I/O操作。当流涉及一个终端时(例如标准输入和标准输出),典型地使用行缓冲。


3.不带缓冲(no buffer)。标准I/O库不对字符进行缓冲。如果用标准I/O函数写若干字符到不带缓冲的流中,则相当于用write系统调用将这些字符写到打开的文件上。标准出错况stderr通常是不带缓存的,这就使得出错信息可以尽快显示出来。

这里强调一下,所谓的带不带缓冲指的是不同的流而不是函数。比如驻留在磁盘上的文件流是全缓冲的方式,标准输入/输出流缺省是行缓冲而标准错误不带缓冲。

行缓冲是指当遇到换行符’/n’或一行满时,才真正的进行I/O操作。Linux缺省情况下一行最多容纳1024个字符,当超出这个范围时,即使没有遇到换行符,也引起实际的I/O操作。

对于全缓冲来说,读写操作是按照缺省的缓冲区大小(4K)进行的。具体说就是从流读取内容时每次读取4K大小的内容到缓冲区,而程序是从缓冲区里读取数据的。当缓冲区里的数据处理完后再从流里读取4K的内容到缓冲区。分析下面的例子:

FILE *fp;
char buf[8192] = {0};  // 缓冲区初始化为0
char ch;

if ( (fp=fopen (“data.txt”, “r+”)) == NULL )
{
   printf(“Fail to open file/n”);
   exit(-1);
}
setvbuf(fp, buf, _IOFBF, 4096);  // 设置流fp为全缓冲,缓冲区指向buf,大小为4096

fread(&ch, 1, 1, fp);  // 从流中读取一个字节的内容存放到变量ch中
printf(“%d  %d  %d/n”, buf[0], buf[1], buf[4095]);

虽然程序在最后一句printf()中只读取了3个字节,但实际上读取了4K的内容存放到buf中。写文件的情况类似,当缓冲区写满内容时才会引起实际的I/O操作,文件被更新。又读又写的情况比较特殊。因为读写缓冲区只有一个,所以在读取内容到缓冲区之前会先把缓冲区里要更新的内容(如果有的话)写到文件。还有一种情况也会引起实际写操作,那就是fseek函数的调用。


2.setvbuf(FILe *stream, char *buffer,int size, size_t size)

remarks:

The setvbuf function allows the program to control both 

buffering and buffer size for stream. stream must refer to an

open file that no undergone an I/o operation since it was opened.

The array pointed to by buffer is used as the buffer, unless it is

NULL, in which case setvbuf uses an automatically allocated buffer

of length size/2*2 bytes.

return value:

Setvbuf returns 0 if successful, or a nonzero vlaue if an

illegal type or buffer size is specified.




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值