C小程序 - setbuf和setvbuf

以下每個小程序,都在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章