【问题标题】:Does fopen return NULL pointer if file is already open?如果文件已经打开,fopen 是否返回 NULL 指针?
【发布时间】:2018-05-01 09:23:09
【问题描述】:

如果文件已经打开,我假设fopen 返回NULL 指针。但看起来fopen 不会返回NULL,以防文件已经在"w" 模式下打开。下面是我用来尝试这个的代码,我没有收到任何错误。我尝试使用 mingw32 以及 TDM-GCC-64 编译器。如果我没记错的话,如果文件已经打开,C++ 会报错。

#include<stdio.h>

int main()
{
    FILE *fp1, *fp2;
    
    fp1 = fopen("file1.txt", "w");
    fp2 = fopen("file1.txt", "w");
    
    if(fp2 == NULL)
    {
        printf("Error in opening file\n");
        return(0);
    }
    
    // Edit: added following code to check the behavior if write operation
    // is performed simultaneously
    
    fputc('A', fp1);
    fputc('M', fp1);
    fputc('S', fp1);
    fputc('B', fp2);
    
    fclose(fp1);
    fclose(fp2);
    
    return 0;
}

编辑:添加了额外的代码以将一些数据写入fp1fp2 并查看行为。如果执行,file1.txt 包含数据 BMS 并且似乎是正确的行为,fp1fp2 按预期独立移动。首先AMS 是使用fp1 编写的,然后A 使用fp2 替换为B,最终输出为BMS

【问题讨论】:

  • 那么发布的代码会发生什么?
  • @Rajesh 这与文件共享有关,在 Windows 上,如果您的 lib 实现调用 _fsopenSH_DENYNO(例如),那么另一个程序(或同一个程序......)可以多次打开文件次(也用于写作)。会发生什么取决于实现和底层操作系统(并发写入并不那么容易,至少在 Windows 上是这样)。但是请注意,默认 fopen() 假定共享,因为通常 *nix 操作系统使用其他同步原语(请参阅 fcntl()
  • 引用:在大多数库实现中,errno 变量也设置为失败时特定于系统的错误代码

标签: c file-handling mingw32


【解决方案1】:

根据 C 标准 (7.19.3.8),它是实现定义的:

打开其他(非临时)文件的函数需要一个文件名,它是一个字符串。组成有效文件名的规则是实现定义的。同一个文件是否可以同时打开多次也是实现定义的。

除此之外,由于其他原因不鼓励这样做,例如参见SEI CERT C Coding Standard's FIO24-C recommendation

某些实现不允许同时打开同一文件的多个副本。因此,可移植代码不能依赖于如果违反此规则会发生什么。即使在没有完全无法打开已打开文件的实现上,也存在 TOCTOU(检查时间,使用时间)竞争条件,其中第二次打开可能会在与第一次不同的文件上操作,因为正在移动或删除的文件(请参阅 FIO45-C。访问文件时避免 TOCTOU 竞争条件以了解有关 TOCTOU 竞争条件的更多详细信息)。

【讨论】:

  • 我添加了额外的代码并编辑了帖子。如果我们尝试同时使用两个文件指针写入,则两者都被写入并且文件指针被独立处理,我想这是正确的行为。
猜你喜欢
  • 1970-01-01
  • 2014-03-10
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多