文件 I/O 中的缓冲区大小

6

我正在尝试编写一个小程序来查找打开文件流的缓冲区大小。在搜索了一下之后,我找到了__fbufsize()函数。这是我编写的代码:

#include <stdio.h>
#include <stdio_ext.h>

void main() {
   FILE *f;
   int bufsize;

   f = fopen("test.txt","wb");
   if (f == NULL) {
      perror("fopen failed\n");
      return;
   }

   bufsize = __fbufsize(f);

   printf("The buffer size is %d\n",bufsize);

   return;
}

我得到的缓冲区大小为零。我有点困惑,不知道为什么会发生这种情况。流默认应该是带缓冲的吧?如果在调用fbufsize之前使用_IOFBF调用setvbuf,则可以获得非零值。


2
<stdio.h>中定义的宏BUFSIZ是默认缓冲区大小。没有标准方法可以找到由setbuf()setvbuf()设置的缓冲区大小。您需要确定您正在使用的平台,以允许有关__fbufsize()作为函数的有用评论(尽管它似乎是GNU libc扩展:__fbufsize())。 - Jonathan Leffler
1
还有一个不错的机会,直到使用文件流之前,缓冲区大小才被设置。在那之前,您可以使用 setvbuf() 更改大小,因此库可能直到尝试使用它之前才设置缓冲区大小。在 printf() 之后添加 fputc('a', f);,然后再次测试大小;现在它可能不再是零了。 - Jonathan Leffler
2个回答

11

注意,main() 的正确返回类型是 int,而不是 void

该代码可以在 Linux 上编译(已测试 Ubuntu 14.04 派生版本):

#include <stdio.h>
#include <stdio_ext.h>

int main(void)
{
    FILE *f;
    size_t bufsize;

    f = fopen("test.txt", "wb");
    if (f == NULL)
    {
        perror("fopen failed\n");
        return -1;
    }

    bufsize = __fbufsize(f);
    printf("The buffer size is %zd\n", bufsize);

    putc('\n', f);
    bufsize = __fbufsize(f);
    printf("The buffer size is %zd\n", bufsize);

    fclose(f);
    return 0;
}

运行时,它产生:

The buffer size is 0
The buffer size is 4096

根据评论建议,在使用文件流之前,缓冲区大小未设置。在此之前,您可以使用setvbuf()更改大小,以便库在尝试使用它之前不设置缓冲区大小。

BUFSIZ<stdio.h>中定义为默认缓冲区大小。没有标准方法可以找到setvbuf()设置的缓冲区大小。您需要确定您正在使用的平台,以允许有关__fbufsize()作为函数的有用评论(尽管它似乎是GNU libc扩展:__fbufsize())。

程序中应该进行许多小的改进,但它们并不是立即相关的。


1
有趣。我也在使用Linux机器(OpenSUSE)。顺便问一下,BUFSIZ的值是否与架构有关?我得到的值是32768。 - npn
1
@npn:这肯定因操作系统而异。在Mac OS X(10.9.5 Mavericks)上,我得到BUFSIZE的1024(64位编译)。经典情况下是512;现在,1024或4096是正常的;32768比我以前见过的都大,但也不算过分。 - Jonathan Leffler
在我的机器上(Linux),BUFSIZ 似乎不是 fread 等函数的默认缓冲区。显式设置缓冲区大小为 BUFSIZ 可以提高性能。很奇怪。 - Nik Tedig

1

__fbufsize 的 man 手册说:

__fbufsize() 函数返回给定流当前使用的缓冲区大小。

因此,我认为这是流使用的缓冲区大小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接