C++仅当文件不存在时才打开文件进行写入

C++ open file for writing only if does not exists

本文关键字:文件 不存在 C++      更新时间:2023-10-16

我想打开一个文件以使用标准库进行写入,但如果该文件已经存在,则文件打开应该会失败。

从我在文档中读到的内容来看,ofstream::open 只允许追加或截断。

我当然可以尝试打开读取以检查文件是否存在,如果不存在,则重新打开以进行写入,但不能保证该文件不会由两者之间的另一个进程创建。

有人可以确认这在标准库(std::iostream)或C函数(FILE*函数)C++是不可能的吗?

由于 C11(因此也在 C++17 中),对于fopen您可以使用模式 "x" — 独占模式,请参阅以下内容:

文件访问模式标志"x"可以选择附加到"w"或"w+" 说明符。如果文件存在,此标志强制函数失败, 而不是覆盖它。

没有fstream方法可以做到这一点,但std::fopen既C++又std::sin

如果你绝对必须有一个fstream这个文件的对象,并且你需要原子检查,你应该首先调用fopen,然后在成功,fclosefstream::open

std::ofstream create_new_file_for_writing()
{
    FILE* fp = nullptr;
    std::string fname;
    do {
        fname = random_file_name(); 
        fp = fopen(fname.c_str(), "wx");
    } while(!fp);
    // here the file is created and you "own" the filename
    fclose(fp);
    return std::ostream(fname);
}

std::ofstream本身,没有。 打开文件进行写入始终会创建一个新文件(如果该文件尚不存在)。 没有更改该行为的选项。 如果文件不存在,则打开文件进行读取将失败。

但是,至少在 Windows 上,Win32 API CreateFile()函数有一个 CREATE_NEW 标志,如果文件已经存在,则无法打开该文件。在其他平台上,可能有可用于_fsopen()的标志,fopen()确实完成了同样的事情。

可以将FILE*附加到std::ofstream(或者我不确定这只是一个Microsoft扩展),并且在Visual C++中,可以通过将_open_osfhandle()_fdopen()一起使用CreateFile()返回的HANDLE创建FILE*。有关示例,请参阅此问题:

我可以使用 CreateFile,但强制句柄进入 std::ofstream 吗?

其他编译器/平台可能会提供类似的扩展来初始化std::ofstream,您将不得不四处寻找。