c - 全缓冲流在未满时被刷新

标签 c buffer

我真的很困惑缓冲区的工作原理。所以我写了一个小片段来验证:

#include<stdio.h>
#define BUF_SIZE 1024 

char buf[BUF_SIZE];
char arr[20];

int main()
{
        FILE* fs=fopen("test.txt","r");
        setvbuf(fs,buf,_IOFBF,1024);
        fread(arr,1,1,fs);
        printf("%s",arr);

        getchar();

        return 0;
}

如您所见,我将文件流 fs 设置为 fully buffered 流(我知道大多数时候它会默认为 fully-buffered。只是确保) .我还将其相关缓冲区的大小设置为 1024,这意味着流不会被刷新,直到它包含 1024 字节的东西(对吗?)。

在我看来,fread()的套路是,它从文件流中读取数据,存入它的缓冲区buf,然后将数据放入buf 将在充满 1024 字节数据后立即发送到 arr(对吗?)。

但是现在,我只从流中读取了一个字符!!而且,文件 test.txt 中也只有四个字符。如果只有一个字符(我可以打印出那个字符),为什么我能在 arr 中找到一些东西

最佳答案

全缓冲、行缓冲和无缓冲之间的区别实际上只对输出流有影响。我很确定输入流几乎总是表现得像是完全缓冲的。

但即使对于完全缓冲的输入流,也至少有一种情况是缓冲区不会完全满,正如您所发现的那样,这就是输入中没有足够的字符来填充缓冲区.如果文件中只有 4 个字符,那么当系统去填充缓冲区时,它会获取这 4 个字符并将它们放入缓冲区,然后你可以像往常一样开始取出它们。

(只要文件中包含的字符数不是缓冲区大小的精确倍数,就会出现同样的情况。例如,如果输入文件包含 1028 个字符,则在用前 1024 个字符填充缓冲区后,让你阅读它们,下次它填充缓冲区时,它会再次以 4 结束。)

在这种情况下,您期望它做什么?阻止等待从文件中再读取 1,020 个字符(这些字符永远不会出现)?

附言你说“流直到它包含 1024 字节的东西才会被刷新,对吧?”但是刷新仅针对输出 流定义;它对输入流没有任何意义。

关于c - 全缓冲流在未满时被刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31094839/

相关文章:

c - 为什么这段代码不起作用?

javascript - 在 nodeJS 中验证 Identity Server 3/4 哈希

c++ - 用 iostream 运算符填充缓冲区

javascript - 如何在不知道原始类型的情况下将缓冲区转换为字符串/数字/日期

tcp - 有人能告诉我 golang 中 io.ReadFull 和 bytes.Buffer.ReadFrom 的行为是什么吗

c - 为什么我得到 "assignment makes pointer from integer without a cast"?

c - 是(char *)NULL-(char *)NULL未定义行为吗?

C: 如何编辑现有文本文件中的一行?

c - C 编程中的堆内存

c# - 如何从字节数组中删除空值?