使用 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 中使用 iostream
或 fstream
来做到这一点?
目前无法以独占模式打开 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";
}
}
编辑:
尽管上面的演示是兼容的并且可以在我测试过的所有平台上运行 - 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 中正常工作。
我想以线程安全的方式创建一个输出文件,并且前提是它不存在。我想使用文件系统进行同步。对于 open()
,我会使用标志 O_RWRONLY|O_CREAT|O_EXCL
。有没有办法在 C++17 中使用 iostream
或 fstream
来做到这一点?
目前无法以独占模式打开 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";
}
}
编辑:
尽管上面的演示是兼容的并且可以在我测试过的所有平台上运行 - 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 中正常工作。