我想用标准库打开一个文件进行写入,但如果该文件已经存在,则打开的文件应该会失败。
根据我在文档中可以阅读的内容,ofstream :: open仅允许追加或截断。
我当然可以尝试打开以进行读取以检查文件是否存在,如果不存在则重新打开以进行写入,但不能保证文件不会被其他进程在中间创建。
有人可以确认这在使用标准库(std :: iostream)或C函数(FILE *函数)的C ++中是不可能的
答案 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
,然后调用fclose
和fstream::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);
}