std:: setvbuf
|
定义于头文件
<cstdio>
|
||
|
int
setvbuf
(
std::
FILE
*
stream,
char
*
buffer,
int
mode,
std::
size_t
size
)
;
|
||
更改给定文件流 stream 的缓冲模式,具体模式由参数 mode 指定。此外,
- 如果 buffer 是空指针,将内部缓冲区大小调整为 size 。
- 如果 buffer 不是空指针,指示流使用从 buffer 开始、大小为 size 的用户提供缓冲区。必须在 buffer 所指向数组的 生命周期 结束前关闭流(使用 std::fclose )。成功调用 std::setvbuf 后,数组内容是不确定的,任何使用该数组的尝试都将导致未定义行为。
目录 |
参数
| stream | - | 要设置缓冲区的文件流 | ||||||
| buffer | - | 指向流使用缓冲区的指针,或空指针(仅用于更改大小和模式) | ||||||
| mode | - |
使用的缓冲模式。可以是下列值之一:
|
||||||
| size | - | 缓冲区大小 |
返回值
0 表示成功,非零值表示失败。
注释
此函数仅可在
stream
已关联打开文件后使用,但必须在任何其他操作之前(除了失败的
std::setbuf
/
std::setvbuf
调用之外)。
并非所有 size 字节都必然用于缓冲:实际缓冲区大小通常会向下取整为2的倍数、页面大小的倍数等。
在许多实现中,行缓冲仅适用于终端输入流。
一个常见的错误是将
stdin
或
stdout
的缓冲区设置为在程序终止前生命周期就已结束的数组:
int main() { char buf[BUFSIZ]; std::setbuf(stdin, buf); } // buf的生命周期结束,未定义行为
默认缓冲区大小
BUFSIZ
预计是实现中文件 I/O 最高效的缓冲区大小,但 POSIX
fstat
通常能提供更准确的估算值。
示例
调整缓冲区大小的一个应用场景是当已知更优的缓冲区大小时。
#include <cstdio> #include <cstdlib> #include <iostream> #include <sys/stat.h> int main() { std::FILE* fp = std::fopen("/tmp/test.txt", "w+"); if (!fp) { std::perror("fopen"); return EXIT_FAILURE; } struct stat stats; if (fstat(fileno(fp), &stats) == -1) // POSIX only { std::perror("fstat"); return EXIT_FAILURE; } std::cout << "BUFSIZ is " << BUFSIZ << ", but optimal block size is " << stats.st_blksize << '\n'; if (std::setvbuf(fp, nullptr, _IOFBF, stats.st_blksize) != 0) { std::perror("setvbuf failed"); // POSIX version sets errno return EXIT_FAILURE; } // Read entire file: use truss/strace to observe the read(2) syscalls used for (int ch; (ch = std::fgetc(fp)) != EOF;) {} std::fclose(fp); return EXIT_SUCCESS; }
可能的输出:
BUFSIZ is 8192, but optimal block size is 65536
参见
|
设置文件流的缓冲区
(函数) |
|
|
[virtual]
|
提供用户指定的缓冲区或使该文件流无缓冲
(
std::basic_filebuf<CharT,Traits>
的虚保护成员函数)
|
|
C 文档
中的
setvbuf
|
|