为什么fflush(input_filestream)不会如联机帮助页所述丢弃Linux上的缓冲区?

时间:2019-03-07 07:36:57

标签: c linux fflush

man fflush在Ubuntu上:

  

对于与可搜索文件(例如,磁盘文件,但不包括管道或终端)相关联的输入流,fflush()丢弃已从基础文件中获取但尚未被应用程序占用的所有缓冲数据。

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

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

在进行网络搜索之前,我完全相信该手册页,现在我想知道它是否错误。


示例代码:

haha​​2.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);
}

1 个答案:

答案 0 :(得分:2)

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

当然,这是假设与此同时文件没有发生任何变化(例如,某些其他进程覆盖文件的一部分,将其截断等)。

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

#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,则代码将在文件中打印第二个字符,因为该文件仍处于缓冲状态(即使实际文件不再包含任何内容)。