为什么 fflush(input_filestream) 不会像联机帮助页描述的那样丢弃 linux 上的缓冲区?

Why fflush(input_filestream) does not discard buffer on linux as manpage describes?

fflush Ubuntu:

For input streams associated with seekable files (e.g., disk files, but not pipes or terminals), fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

我读过一些关于 fflush(stdin)fflush() 的问题,根据标准,输入流是未定义的行为,没错。但是对于 Linux 具体来说,我读过评论说它不是未定义的行为而是扩展,是的,上面的联机帮助页说明了它如何在文件输入流上工作。

那么,为什么 fflush() 输入文件流不丢弃 已从基础文件中获取但尚未被应用程序使用的缓冲数据。 作为联机帮助页描述?

在网上搜索之前我完全相信联机帮助页,现在我想知道它是否有误。


示例代码:

haha2.txt: 123456,没有换行符或空格。

#include <stdio.h>

int
main()
{
    FILE* fp = fopen("haha2.txt", "r");
    int q = getc(fp);
    fflush(fp);
    int j = getc(fp); // I expect the rest variables to be -1(EOF) starting from here
    int j2 = getc(fp);// But they can still read data as if fflush does not executed
    int j3 = getc(fp);
    int j4 = getc(fp);

    int j5 = getc(fp);
    int j6 = getc(fp);
    int j7 = getc(fp);
    int j8 = getc(fp); 
    printf("%c,%c,%c,%c,%c,%c,%c,%c\n", j,j2,j3,j4,j5,j6,j7,j8);
    return(0);
}

刷新文件缓冲区只会丢弃缓冲区中的数据。它不会影响文件的内容。随后的读取将继续读取文件,就好像什么也没发生一样(除了首先必须再次填充缓冲区)。

当然,这假设文件在此期间没有发生任何事情(例如,一些其他进程覆盖了文件的一部分,t运行cating 它,等等)。

为了说明,如果您修改代码以在 fflush 之后包含一个 sleep

#include <stdio.h>
#include <unistd.h>

int main() {
    FILE* fp = fopen("haha2.txt", "r");
    int q = getc(fp);
    fflush(fp);
    sleep(10);
    int j = getc(fp); // I expect the rest variables to be -1(EOF) starting from here
    printf("%d\n", j);
    return(0);
}

当您 运行 此代码,并在另一个终端中,您 运行 在睡眠期间执行此命令(此命令将从文件中删除所有内容并将其大小设置为 0):

truncate -s0 haha2.txt

然后代码将打印-1(因为已经到达文件末尾)。

如果您再次尝试相同的操作(确保先将您的测试数据添加回文件),但这次没有 fflush,代码将打印文件中的第二个字符,因为文件的开头仍被缓冲(即使实际文件不再包含任何内容)。