【问题标题】:What is the C++ iostream to creating a file with O_EXCL?使用 O_EXCL 创建文件的 C++ iostream 是什么?
【发布时间】:2021-11-25 18:49:20
【问题描述】:

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

【问题讨论】:

  • 不,这是特定于操作系统的东西。
  • C23 和 C++23 正在考虑在各自的标准库中对此提供适当的支持。 POSIX 当然定义了 fdopenO_EXCL,但没有可移植的 C++ 等价物。
  • 谢谢。如果您使用 C++23,最好有一种基于标准的方式来处理内存映射文件。

标签: c++17 fstream iostream ofstream


【解决方案1】:

目前无法以独占模式打开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) 无法处理它,所以我在bugs.winehq.org 上打开了一个错误报告。您可以在此处关注进度:

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 中正常工作。

【讨论】:

  • 这在 WIN32 上是否可以使用 mingw?
  • @vy32 如果它完全符合 C++17,是的。
  • 太棒了。我会试一试。谢谢!我希望fclose() 会采用std::string,但我想我不能拥有一切。
  • @vy32 :-) 是的 - fopen/fclose 是 C 的传统 - 但它在这种情况下也有其用途。
  • 遗憾的是,它不符合 C++17。我收到此错误消息:00fc:err:msvcrt:msvcrt_get_flags incorrect mode flag: x。 (在 Wine 下运行)
猜你喜欢
  • 2018-07-01
  • 2011-07-26
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2011-05-27
  • 2014-06-27
  • 1970-01-01
相关资源
最近更新 更多