【发布时间】:2010-04-19 18:46:20
【问题描述】:
所以 FILE 流可以同时具有输入和输出缓冲区。您可以使用setvbuf 调整输出流(我不知道有任何方法可以使用输入缓冲区大小和行为)。
此外,默认情况下缓冲区是BUFSIZ(不确定这是 POSIX 还是 C 事物)。很清楚这对stdin/stdout/stderr 意味着什么,但是新打开的文件的默认值是什么?它们是否为输入和输出缓冲?或者也许只有一个?
如果是缓冲的,输出默认是块模式还是行模式?
编辑:我做了一些测试,看看 Jonathan Leffler 的回答如何影响现实世界的程序。看来,如果你先读然后写。写入将导致输入缓冲区的未使用部分完全丢弃。实际上,将进行一些查找以将内容保持在正确的文件偏移量处。我使用了这个简单的测试程序:
/* input file contains "ABCDEFGHIJKLMNOPQRSTUVWXYZ" */
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f = fopen("test.txt", "r+b");
char ch;
fread(&ch, 1, 1, f);
fwrite("test", 4, 1, f);
fclose(f);
return 0;
}
导致以下系统调用:
read(3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 4096) = 27 // attempt to read 4096 chars, got 27
lseek(3, -26, SEEK_CUR) = 1 // at this point, I've done my write already, so forget the 26 chars I never asked for and seek to where I should be if we really just read one character...
write(3, "test", 4) = 4 // and write my test
close(3) = 0
虽然这些显然是实现细节,但就如何实现标准库而言,我发现它们非常有趣。感谢乔纳森您富有洞察力的回答。
【问题讨论】:
-
BUFSIZ 在 C 标准中 - 因此它也在 POSIX 中。
-
未定义的行为:您必须在
fread()和fwrite()之间使用fseek()- 如果您不这样做,实现可能会随心所欲(这可能是也可能不是您想要的) .