提问人:vy32 提问时间:10/5/2021 更新时间:1/29/2023 访问量:328
使用 O_EXCL 创建文件的 iostream C++是什么?
What is the C++ iostream to creating a file with O_EXCL?
问:
我想以线程安全的方式创建一个输出文件,并且仅在它不存在的情况下。我想使用文件系统进行同步。我会使用标志.有没有办法在 C++17 中使用 or ?open()
O_RWRONLY|O_CREAT|O_EXCL
iostream
fstream
答:
2赞
Ted Lyngmo
10/5/2021
#1
在 C++23 之前,无法打开独占模式。ofstream
解决方法:使用 std::fopen
,它从 C++17 开始具有此功能。
例:
#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";
}
}
编辑:
尽管上面的演示是兼容的并且适用于所有平台,但我已经测试过了 - (v6.16) 无法处理它,所以我在 bugs.winehq.org 打开了错误报告。您可以在此处跟踪进度:wine
无法识别标准库调用 fopen(..., “wx”)
- 导致数据破坏
编辑2:
Wine 错误修复 ucrtbase: Add support for x mode in fopen 现在包含在 Wine 6.20 中,因此在升级到 6.20(或更高版本)后,它也将在 Wine 中正常工作。
从 C++23 开始,您可以使用 openmode
:std::ios::noreplace
std::ofstream os("filename", std::ios::noreplace);
if(os) {
std::cout << "file created exclusively\n";
}
评论
0赞
vy32
10/5/2021
这适用于带有 mingw 的 WIN32 吗?
1赞
Ted Lyngmo
10/5/2021
@vy32 如果它完全符合 C++17,是的。
0赞
vy32
10/5/2021
伟大。我会试一试。谢谢!我希望这需要一段时间,但我想我不能拥有一切。fclose()
std::string
0赞
Ted Lyngmo
10/5/2021
@vy32 :-)True - / 是 C 的遗留问题 - 但它有其用途,就像在这种情况下一样。fopen
fclose
0赞
vy32
10/5/2021
可悲的是,它不符合 C++17 标准。我收到以下错误消息: .(在 Wine 下运行)00fc:err:msvcrt:msvcrt_get_flags incorrect mode flag: x
上一个:显示整个文件
评论
fdopen
O_EXCL