C++ 如何打开文件进行阅读&;写,如果它不存在,创建它,而不截断它?
对于C++ 如何打开文件进行阅读&;写,如果它不存在,创建它,而不截断它?,c++,iostream,fstream,c++03,C++,Iostream,Fstream,C++03,对于std::fstream,我希望能够读取和写入文件的I/O标志的正确设置是什么?如果文件存在,则不截断文件,如果不存在,则创建文件 我试过了 std::ios::binary | std::ios::in | std::ios::out std::ios::binary | std::ios::in | std::ios::out | std::ios::ate 但是,如果文件不存在,这两种方法都不会创建该文件 我不想要std::ios::app,因为我还需要能够使用get和put游标随意
std::fstream
,我希望能够读取和写入文件的I/O标志的正确设置是什么?如果文件存在,则不截断文件,如果不存在,则创建文件
我试过了
std::ios::binary | std::ios::in | std::ios::out
std::ios::binary | std::ios::in | std::ios::out | std::ios::ate
但是,如果文件不存在,这两种方法都不会创建该文件
我不想要std::ios::app
,因为我还需要能够使用get和put游标随意查找文件
我想,一种解决方法是首先实例化一个
std::ofstream
,然后立即关闭它并打开我真正想要的流,但如果可以用一个流对象来避免的话,这看起来很混乱。此时,我的结论是std::ios::in
彻底阻止了这一点,我必须使用变通方法
因此:
读取
std::ios::binary
,您可能需要的剩余openmode
是:
std::ios::in | std::ios::app
其效果就像打开文件时使用:
std::fopen(filename,"a+")
其效果是:
- 打开或(如果不存在)创建用于读写的文件
- 在文件末尾写入数据
openmode
以std::fstream
的形式打开文件,则如果文件存在,它不会被截断。你可以
从文件中读取fstream
的tellg()\tellp()
指针指向的任何位置,
只要有东西可以读,你就可以定位那个指针
使用流的seekg()\seekp()
进行读取。但是,所有写入操作都将被删除
附加到文件末尾
因此,除非您需要执行写操作,否则此openmode将适合您的账单
现有数据。一项调查,从Linux的角度来看(尽管其中大部分可能适用于其他Unice): 在系统调用层,您需要
open(O|RDWR | O|u create,0666)
(但不是O|u TRUNC
或O|u APPEND
或一系列其他标志,尽管可以说所有文件都应该使用O|u CLOEXEC | O|u LARGEFILE
打开,但这不是重点)
在libc层,没有标准的模式
字符串表示O_create
而没有O_TRUNC
。但是,您可以使用open
后跟fdopen
在C++库级别,没有标准的方法传递希望的标志。但是,使用特定于实现的类/函数或第三方库是可能的;看
就我个人而言,我倾向于在C甚至系统调用级别进行所有I/O,因为API更好,更可预测。对于类实例的输入/输出,我有自己的模板。创建尝试不需要进行失败检查或报告。另外,我认为您不需要在c++11及更高版本中使用
c_str()。Boost文件系统可能会为您做这件事(我不知道),如果是这样,那么您只需等到C++17即可@Cheersandhth.-Alf作为标记(c++03),似乎是c_str()
的原因,尽管如果有人阅读这篇文章要使用c++11或更高版本,你显然是对的。顺便说一句,03x中没有包含std::string
构造吗?@WhozCraig:没有,C++03中唯一的新东西是值初始化。@cheers-sandhth.-Alf-ah.。那么所有这些C_str
与该标记结合起来确实有意义。谢谢你的信息@轻量级在轨道上比赛,我相信你在调用std::ostream
构造函数时忘记添加std::ios::binary | std::ios::app
。如果没有这些标志,该文件将被截断,以防它已经存在,这是您说您不想要的。当我偶然发现这一点时,我也没有:)谢谢,关闭,但是:“我不想要std::ios::app
,因为我还需要能够使用get和put游标随意查找文件。”
std::fopen(filename,"a+")