C ++打开文件只有在不存在的情况下才能写入

时间:2016-06-08 17:44:13

标签: c++ c file std

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

根据我在文档中可以阅读的内容,ofstream :: open仅允许追加或截断。

我当然可以尝试打开以进行读取以检查文件是否存在,如果不存在则重新打开以进行写入,但不能保证文件不会被其他进程在中间创建。

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

3 个答案:

答案 0 :(得分:7)

从C11开始(因此也在C ++ 17中),对于fopen,您可以使用模式"x" - 独占模式,请参阅this

  

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

答案 1 :(得分:1)

单独std::ofstream,不。打开要写入的文件始终会创建一个新文件(如果该文件尚不存在)。没有选择来改变这种行为。如果文件不存在,则打开文件进行读取失败。

但是,至少在Windows上,Win32 API CreateFile()函数有一个CREATE_NEW标志,如果该文件已经存在,则无法打开该文件。在其他平台上,_fsopen()fopen()可能会有标记可以完成相同的操作。

可以将FILE*附加到std::ofstream(或者这可能只是Microsoft扩展,我不确定),在Visual C ++中可以创建FILE*对于HANDLE CreateFile()使用_open_osfhandle() _fdopen()返回的std::ofstream。请参阅此问题以获取示例:

Can I use CreateFile, but force the handle into a std::ofstream?

其他编译器/平台可能会为初始化{{1}}提供类似的扩展,您必须环顾四周。

答案 2 :(得分:1)

没有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);
}