setbuf与setvbuf函数,C语言setbuf与setvbuf函数详解
发布时间:2020-12-15 17:32:56 所属栏目:百科 来源:网络整理
导读:在讨论 setvbuf 与 setbuf 函数之前,先来看如下一段示例代码: int main(void){ FILE* fp=NULL; int fd; const char *f1="testfprintf.log"; const char *f2="testwrite.log"; fp = fopen(f1,"wb"); if(fp == NULL) { return -1; } fd = open(f2,O_WRONLY|O_
在讨论 setvbuf 与 setbuf 函数之前,先来看如下一段示例代码:int main(void) { FILE* fp=NULL; int fd; const char *f1="testfprintf.log"; const char *f2="testwrite.log"; fp = fopen(f1,"wb"); if(fp == NULL) { return -1; } fd = open(f2,O_WRONLY|O_CREAT|O_EXCL,0666); if(fd < 0) { return -1; } while(1) { fprintf(fp,"fprintf------|n"); write(fd,"write|n",sizeof("write|n")); sleep(1); } return 0; }在上面的示例代码中,使用 fprintf 函数对文件 testfprintf.log 执行写入操作,使用 write 函数对文件 testwrite.log 执行写入操作。这里需要注意的是,因为 fprintf 函数会缓冲 4096 字节的数据,只有当达到这么多字节的数据时才会进行实际的磁盘写入。 因此,运行上面的示例程序,然后实时查看 testfprintf.log 文件与 testwrite.log 文件,会发现 testfprintf.log 文件不会被实时写入,只有当写入的数据的大小为 4096 字节的倍数的时候才会被写入;而 write 函数则不同,因为它不进行任何缓冲(直接写入磁盘),所以文件 testwrite.log 不断有数据写入,运行结果如图 1 所示。 ![]() 图 1 示例代码的运行结果 在上面的示例中不难发现,通过提供缓冲区可以尽可能减少 read 和 write 调用的次数,从而降低执行 I/O 的时间。在 C 语言中,标准 I/O 库提供了 3 种类型的缓冲。 1) 全缓冲在进行 I/O 操作时,只有当 I/O 缓冲区被填满时,才进行实际的 I/O 操作。对于驻留在磁盘上的文件,通常就是由标准 I/O 库来实施全缓冲的。在一个流上执行第一次 I/O 操作时,相关标准 I/O 函数通常调用 malloc 来获得需要使用的缓冲区。在默认情况下,全缓冲的缓冲区可以由标准 I/O 例程自动刷新。当然,也可以通过调用 fflush 函数来强制刷新一个数据流。但需要特别注意的是,在标准 I/O 库方面,flush 函数意味着将缓冲区中的内容写到磁盘上;而在终端驱动程序方面,flush 函数则表示丢弃已存储在缓冲区中的数据。 2) 行缓冲在这种情况下,只有当在输入和输出中遇到换行符时,才执行实际的 I/O 作。当然,因为标准 I/O 库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,即使还没有写一个换行符,也必须进行 I/O 操作。很显然,它允许我们一次输出一个字符(如 fputc 函数),但只有在写完一行之后才进行实际 I/O 操作。当流涉及一个终端时,通常使用行缓冲。例如,使用最频繁的 printf 函数就是采用行缓冲,所以感觉不出缓冲的存在。 3) 不带缓冲标准 IO 库不对字符进行缓冲存储。在一般情况下,标准错误流 stderr 通常也是不带缓冲的。相对于这些系统默认的情况,也可以通过调用标准库函数 setbuf 和 setvbuf 来更改缓冲类型。函数 setbuf 和 setvbuf 将使得在打开文件后用户可以建立自己的文件缓冲区,而不使用由 fopen 函数打开文件所设定的默认缓冲区。函数 setbuf 和 setvbuf 的一般函数原型如下所示:
void setbuf(FILE *fp,char *buf); 对于 setbuf 函数,当指定参数 buf 为 null 时,setbuf 函数将使得文件 I/O 不带缓冲。如下面的示例代码所示: setbuf(fp,NULL);对 setvbuf 函数来说,由于 setbuf 函数没有返回值,因此也无法确定 setbuf 函数的调用是否成功。在实际使用中,应该尽量使用 setvbuf 来替换 setbuf 函数,以验证流被成功地更改。如下面的示例代码所示: if (setvbuf(file,buf,buf ? _IOFBF : _IONBF,BUFSIZ) != 0) { } 对 setvbuf 函数,则由 malloc 函数来分配缓冲区,参数 size 指明了缓冲区的长度(必须大于 0),而参数 mode 则表示缓冲的类型,取值如下所示:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |