You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

疑问:fopen函数在文件已打开时是否返回NULL指针?实测w模式未返回NULL

为什么以"w"模式重复打开同一文件时fopen不返回NULL?

你的假设其实是对C标准和操作系统文件行为的常见误解——C语言标准并没有规定当文件已被打开时,再次调用fopen会返回NULL。实际行为取决于你使用的操作系统和编译器实现,这也是你测试时没看到错误的核心原因。

先明确fopen("w")的标准行为

根据C标准,用"w"模式打开文件时会执行两个核心操作:

  • 如果文件已存在,**立即截断(清空)**文件内容;
  • 打开文件以进行写入操作(如果文件不存在则创建)。

这里的关键是:操作系统默认允许多个文件流(或进程)同时打开同一个文件,哪怕其中已经有一个是写入模式打开的。你的测试环境是Windows(mingw32和TDM-GCC都是Windows平台的编译器),Windows下fopen默认的文件共享模式是_SH_DENYNO——也就是允许其他句柄读写这个文件,所以第二次fopen调用完全合法,会成功返回有效的文件指针,同时再次截断文件。

关于你印象里的C++报错

你提到C中重复打开会报错,这其实是特定标准库实现的行为,不是C强制要求的。比如在Windows的MSVC标准库中,当你用std::ofstream默认打开文件时,它会使用不允许其他写入操作的共享模式——如果文件已经被其他句柄以写入模式打开,ofstream的打开操作就会失败,设置failbit,这让你产生了"C++会报错"的印象,但这不是跨平台的通用行为。

补全你的测试代码并验证

你提供的测试代码没写完,补全后大概是这样:

#include<stdio.h>
int main() {
    FILE *fp1, *fp2;
    fp1 = fopen("file1.txt", "w");
    fp2 = fopen("file1.txt", "w");
    
    if (fp1 == NULL || fp2 == NULL) {
        printf("Open failed!\n");
        return 1;
    }
    
    fprintf(fp1, "Hello from fp1\n");
    fprintf(fp2, "Hello from fp2\n");
    
    fclose(fp1);
    fclose(fp2);
    return 0;
}

运行这段代码后,你会发现file1.txt里最终只有Hello from fp2——因为第二个fopen调用截断了文件,覆盖了第一个流写入的内容(如果没有手动刷新缓冲区,第一个流的内容可能还没写入磁盘就被截断了)。

如果想让重复打开失败怎么办?

如果需要确保同一时间只有一个文件流能打开某个文件进行写入,你需要依赖操作系统的文件锁定机制:

  • 在Windows下,可以使用_fsopen函数,指定_SH_DENYWR共享模式,这样当文件已被写入模式打开时,后续打开会失败;
  • 在Linux下,可以用flock或fcntl函数给文件加锁,阻止其他进程打开。

内容的提问来源于stack exchange,提问作者Rajesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:59:30