C小程序 - setbuf和setvbuf

本文通过几个简单的C程序实例,探讨了标准I/O库在处理文件写入时的缓存机制,包括全缓存、无缓存及行缓存的不同表现,并解释了不同情况下缓存刷新的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下每个小程序,都在sleep(100)的时候,去cat文件12345.txt的内容

  1. #include <stdio.h>

  2. main()
  3. {
  4.         char * str = "abcde";
  5.         FILE * fp = fopen("12345.txt", "w");
  6.         fwrite(str, sizeof(char), strlen(str), fp);
  7.         sleep(100);
  8. }
$cat 12345.txt
没有内容

  1. #include <stdio.h>

  2. main()
  3. {
  4.         char * str = "abcde\n";
  5.         FILE * fp = fopen("12345.txt", "w");
  6.         fwrite(str, sizeof(char), strlen(str), fp);
  7.         sleep(100);
  8. }
$cat 12345.txt
没有内容, 说明对于驻在磁盘上的文件通常是由标准I/O库实施全缓存的, 所以即使遇到换行符,也不会输出。

  1. #include <stdio.h>

  2. main()
  3. {
  4.         char * str = "abcde";
  5.         FILE * fp = fopen("12345.txt", "w");
  6.         setbuf(fp, NULL); //设置无缓冲
  7.         fwrite(str, sizeof(char), strlen(str), fp);
  8.         sleep(100);
  9. }
$cat 12345.txt
abcde
由于设置了无缓冲,所以直接就输出到文件了。

  1. #include <stdio.h>

  2. main()
  3. {
  4.         char * str = "abcde";
  5.         char * buf = (char *)malloc(20);
  6.         FILE * fp = fopen("12345.txt", "w");
  7.         setvbuf(fp, buf, _IOLBF, 20); //设置行缓冲

  8.         fwrite(str, sizeof(char), strlen(str), fp);

  9.         sleep(100);
  10. }

$cat 12345.txt
abcde
这个结果很让我奇怪,我本来以为我设置了一个20长度的行缓冲区,但是我只是输出6个字符,没有填满缓冲区,所以不应该有输出到文件,但是没想到,在sleep的时候去cat文件,发现内容已经写到了文件中,说明行缓冲区已经被填满。。。我很疑惑,然后我尝试把行缓冲区的大小扩大到200

#include 

main()
{
        char * str = "abcde";
        char * buf = (char *)malloc(200);
        FILE * fp = fopen("12345.txt", "w");
        setvbuf(fp, buf, _IOLBF, 200);

        fwrite(str, sizeof(char), strlen(str), fp);

        sleep(100);
}

$cat 12345.txt
没有内容。扩大了行缓冲区后,这次没有内容输出到文件。所以我猜想内核肯定也会利用这个缓冲区做一些事情,而不只是单单把要输出的内容放进去,所以如果这个行缓冲区的大小比较小的话,虽然看起来能容纳下要输出的内容,但是很可能已经被系统内核的一些信息占了一些空间,所以有一点点输出也许就填满了缓冲区,从而就刷新到了文件里。不知道我这个理解对不对????


  1. #include <stdio.h>

  2. main()
  3. {
  4.         char * str = "abc\nde"; //在要输出的字符串中间加上换行符,强制刷新缓冲区
  5.         char * buf = (char *)malloc(200);
  6.         FILE * fp = fopen("12345.txt", "w");
  7.         setvbuf(fp, buf, _IOLBF, 200);

  8.         fwrite(str, sizeof(char), strlen(str), fp);

  9.         sleep(100);
  10. }
$cat 12345.txt
abc
可以看到,换行符之前的字符串已经输出了,后面的还在缓冲区里没有输出的文件。另外让程序自行结束后,
$cat 12345.txt
abc
de

可以看到,剩下在缓冲区的内容,在程序退出时候,标准I/O库会自动关闭此流并刷新缓冲区。


转自:http://blog.chinaunix.net/uid-1911213-id-3412402.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值