Namespaces
Variants

setvbuf

From cppreference.net
< c ‎ | io
定义于头文件 <stdio.h>
int setvbuf ( FILE * stream, char * buffer,
int mode, size_t size ) ;
(C99前)
int setvbuf ( FILE * restrict stream, char * restrict buffer,
int mode, size_t size ) ;
(C99起)
#define _IOFBF     /*unspecified*/

#define _IOLBF     /*unspecified*/

#define _IONBF     /*unspecified*/

更改给定文件流 stream 的缓冲模式,具体由参数 mode 指示。此外,

  • buffer 为空指针,将内部缓冲区大小调整为 size
  • buffer 非空指针,指示流使用用户提供的、起始地址为 buffer 且大小为 size 的缓冲区。必须在 buffer 所指数组的 生命周期 结束前关闭流(通过 fclose )。成功调用 setvbuf 后数组内容是不确定的,任何使用该数组的尝试均属于未定义行为。

目录

参数

stream - 要设置缓冲区的文件流
buffer - 指向流使用缓冲区的指针,或空指针(仅用于更改大小和模式)
mode - 使用的缓冲模式。可以是下列值之一:
_IOFBF 全缓冲
_IOLBF 行缓冲
_IONBF 无缓冲
size - 缓冲区大小

返回值

0 表示成功,非零值表示失败。

注释

此函数仅可在 stream 已与打开文件关联后、执行任何其他操作前使用(失败的 setbuf / setvbuf 调用除外)。

并非所有 size 字节都必然用于缓冲:实际缓冲区大小通常会向下取整为2的倍数、页大小的倍数等。

在许多实现中,行缓冲仅适用于终端输入流。

一个常见错误是将 stdin 或 stdout 的缓冲区设置为在程序终止前生命周期就已结束的数组:

int main(void) {
    char buf[BUFSIZ];
    setbuf(stdin, buf);
} // buf 的生命周期结束,未定义行为

默认缓冲区大小 BUFSIZ 预计是实现上文件I/O最高效的缓冲区尺寸,但POSIX fstat 通常能提供更准确的估算值。

示例

调整缓冲区大小的一个应用场景是已知更优尺寸时。(此示例使用部分POSIX函数,例如 fileno 。另请参阅Stack Overflow: #1 #2 )。

// Make some POSIX functions, such as `int fileno(FILE*)`, visible:
#define _POSIX_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(void)
{
    FILE* fp = fopen("/tmp/test.txt", "w+");
    if (fp == NULL)
    {
        perror("fopen");
        return EXIT_FAILURE;
    }
    struct stat stats;
    if (fstat(fileno(fp), &stats) == -1) // POSIX only
    {
        perror("fstat");
        return EXIT_FAILURE;
    }
    printf("BUFSIZ is %d, but optimal block size is %ld\n", BUFSIZ, stats.st_blksize);
    if (setvbuf(fp, NULL, _IOFBF, stats.st_blksize) != 0)
    {
        perror("setvbuf failed"); // POSIX version sets errno
        return EXIT_FAILURE;
    }
    int ch;
    while((ch=fgetc(fp)) != EOF); // read entire file: use truss/strace to
                                  // observe the read(2) syscalls used
    fclose(fp);
    return EXIT_SUCCESS;
}

可能的输出:

BUFSIZ is 8192, but optimal block size is 65536

参考文献

  • C17 标准 (ISO/IEC 9899:2018):
  • 7.21.5.6 setvbuf 函数 (p: 225)
  • C11 标准 (ISO/IEC 9899:2011):
  • 7.21.5.6 setvbuf 函数 (p: 308)
  • C99标准(ISO/IEC 9899:1999):
  • 7.19.5.6 setvbuf函数(页码:273-274)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 4.9.5.6 setvbuf 函数

参见

设置文件流的缓冲区
(函数)
C++ 文档 关于 setvbuf