【问题标题】:fread isnt reading an updated value despite the file has been changed by another program尽管文件已被另一个程序更改,但 fread 未读取更新的值
【发布时间】:2017-01-13 19:25:10
【问题描述】:

有两个程序同时处理我的特殊文件。他们有一个共同的起点:

    #define TASK_POSITION 0x0100

    #include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>

    int main() {

        FILE * control_file;
        unsigned int task_code;
        fpos_t task_position;

        control_file = fopen("/home/anonymous/.control", "r+");
        fseek(control_file, TASK_POSITION, SEEK_SET);
        fgetpos(control_file, &task_position);

但后来他们有一个非常不同的代码

  • 第一个程序可以更改此文件的 TASK_POSITION 偏移处的值:

        /* ... lots of code there ... */
    
        task_code = 0xFEEDFACE;
    
        fsetpos(control_file, &task_position);
        fwrite(&task_code, 4, 1, control_file);
          fflush(control_file);
            sleep(1);
    
        fclose(control_file);
        return 0;
    }
    
  • 第二个程序在这个文件的相同偏移量处重复读取一个值:

        for (;;) {
            fsetpos(control_file, &task_position);
            fread(&task_code, 4, 1, control_file);
            if (task_code == 0xFEEDFACE) {
                /* ... Do something awesome! ... */
            }
            else { // remove after debugging
              fprintf(stdout, "not hungry yet :P 0x%08x value has been read... \n"); 
              fflush(stdout);
            }
            sleep(60);
        }
    
        // just in case
        fclose(control_file);
        return 0; 
    }
    

默认情况下,TASK_POSITION 偏移处存储 0x12345678 值。

这里有个问题:

在第一个程序启动并完成其工作后,我可以在十六进制编辑器中看到一个特殊文件已成功更改。但是:由于某些我不知道的原因,第二个程序的 fread 一直读取相同的旧值 - 0x12345678!

虽然我在第二个程序的无限循环(在 fread 检查之间)的每次迭代期间通过关闭/打开此文件找到了一个临时解决方法,但它看起来并不是最好的解决方案!请告诉:如何强制 fread 从文件中实际重新读取新值,而不是仅返回先前读取的值(从其缓存中??)?

【问题讨论】:

    标签: c file gcc fwrite fread


    【解决方案1】:

    C 的标准 I/O 函数通常是缓冲的。要禁用缓冲,您可以这样做:

    setvbuf(control_file, NULL, _IONBUF, 0);
    

    立即在您打开文件之后,在您对其执行任何 I/O 之前。

    【讨论】:

    • 你的回答真的很有帮助!因为当我尝试用谷歌搜索这个问题时,我没有找到任何答案(并且想到了缓存而不是缓冲区)非常感谢!多亏了你,现在我可以优雅地喂那张脸了 ;-)
    • 如果您只是将缓冲区设置为通过它的上一条消息的大小或下一条消息的大小,以较大者为准?可用的缓冲区通常会加快处理速度,所以我对摆脱它的想法有点犹豫,但我也不喜欢硬编码限制,除非他们有充分的理由。
    • @kayleeFrye_onDeck 我怀疑这会有所帮助;您仍然可以读取过时的缓存值。缓冲有用的;这是一种相当罕见的情况,您想要禁用它。如果您有不同的情况需要缓冲但可能会读取过时的数据,那么也许您应该针对自己的情况提出一个单独的问题。
    • @jamesdlin 这很有道理。如果您禁用它,然后立即重新启用它会怎样?
    猜你喜欢
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 2019-08-18
    • 2021-07-18
    • 2012-11-20
    • 2016-08-02
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多