fclose会立即释放文件吗?

时间:2018-05-09 14:23:32

标签: c fopen fclose

我有2个功能。第一个函数是在写入模式下打开文件并向其写入一些内容然后关闭它。

FILE *fp = fopen("file.txt", "w");
//writing itnot file using fwrite
fclose(fp);

第二个函数以读取模式打开文件,解析内容然后关闭文件。

FILE *fp = fopen("file.txt", "r");
//parsing logic
fclose(fp);

main中,我按顺序呼叫function1function2

int main()
{
    function1();
    function2();
    return 1;
}

有时,function1 fopen失败,错误号为13,即权限被拒绝。我有时只是观察这一点。我在sleep之后的function1中引入了fclose 2秒钟,它开始正常运行,没有任何问题。

所以我怀疑文件在fclose之后没有立即发布。睡眠不是正确的解决方案。任何人都可以建议如何解决这个问题?我在这里给出的示例是一个用例,实际代码在线程环境中运行。

2 个答案:

答案 0 :(得分:1)

C11的N1570草案称为7.21.5.1 fclose函数

  

成功调用fclose函数会导致stream指向的流   刷新并关闭相关文件。流的任何未写入的缓冲数据   被传递到主机环境以写入文件;任何未读缓冲数据   被丢弃了。无论呼叫是否成功,流都将与文件解除关联   并且setbuf或setvbuf函数设置的任何缓冲区都与流取消关联   (如果自动分配,则解除分配)。

它没有假设在主机环境级别发生了什么,也就是说,该函数仅在整个操作完成时返回,或者在请求排队后立即返回。

由于竞争条件可能会在您的环境中发生,因此您应该多次尝试失败打开,最终会在它们之间出现延迟。如果可移植性不是问题,并且您的系统支持POSIX sync功能,则还可以在关闭文件后强制执行磁盘同步:

  • 关闭部分:

    ...
    fclose(fp)
    sync();         // forces synchronization of io buffers to disk 
    
  • 重新开放部分

    ntries = ...;   // number of open tries
    while (ntries-- > 0) {
        fp = fopen(...);
        if (fp != NULL) break;   // open was successful
        // optionaly add a delay
    }
    

答案 1 :(得分:0)

在一个环境中并且在C实现中你必须适应这种行为,最好的方法可能是在fopen()周围实现一些容错。虽然无条件 sleep()不是正确答案,但通过sleep()或类似函数的短暂条件延迟可能确实是此类策略的一部分。例如,您可以沿着这些方向做点什么:

#include <stdio.h>
#include <errno.h>
#define MAX_ATTEMPTS 3

FILE *tolerant_fopen(const char *path, const char *mode) {
    FILE *result;
    int attempts = 0;

    while (!(result = fopen(path, mode))) {
        if (errno != EACCES || attempts >= MAX_ATTEMPTS) {
            break;
        }
        if (sleep(1) == 0) {
            attempts += 1;
        }
    }

    return result;
}

尝试立即打开文件,如果由于访问权限而失败,它会等待很短的时间然后再次尝试。总的来说,它可能会进行三次或更多次尝试打开文件,间隔一秒或者稍微多一点。 (注意sleep()可以提前中断;在这种情况下,它会返回剩余的秒数。)

如果您愿意,您当然可以针对重试的时间和持续时间实施不同的策略,重试更多错误条件, ..