使用 O_EXCL 创建文件的 C++ iostream 是什么?

What is the C++ iostream to creating a file with O_EXCL?

我想以线程安全的方式创建一个输出文件,并且前提是它不存在。我想使用文件系统进行同步。对于 open(),我会使用标志 O_RWRONLY|O_CREAT|O_EXCL。有没有办法在 C++17 中使用 iostreamfstream 来做到这一点?

目前无法以独占模式打开 ofstream

解决方法:使用自 C++17 起具有此功能的 std::fopen

示例:

#include <cstdio>

// Mode "x" to make it fail if it already exists
std::FILE* fp = std::fopen("filename", "wx");

if(fp) {
    // created exclusively

    // work with fp ...

    std::fclose(fp);
}

如果你真的想要一个 ofstream 你可以创建一个辅助函数:

template<class Stream>
Stream open_exclusively(const std::string& filename) {
    Stream rv;
    
    if(std::FILE* fp = std::fopen(filename.c_str(), "wx"); fp) {
        std::fclose(fp);

        // overwrite the file that was created exclusively:
        rv.open(filename);
    } else {
        // could not create file exclusivly, set the failbit in the stream:
        rv.setstate(Stream::failbit);
    }

    return rv;
}

int main() {
    auto os = open_exclusively<std::ofstream>("filename");

    if(os) {
        std::cout << "file created exclusively\n";
    }
}

Demo

编辑:

尽管上面的演示是兼容的并且可以在我测试过的所有平台上运行 - wine (v6.16) 无法处理它,所以我在 [=19= 打开了一个错误报告].您可以在此处关注进度:

Standard library call fopen(..., "wx") not recognized - causes destruction of data

编辑 2:

Wine 错误修复 ucrtbase: Add support for x mode in fopen 现在包含在 Wine 6.20 中,因此在升级到 6.20(或更高版本)后,这也将在 Wine 中正常工作。