当 C++ 创建std::ofstream它时,它立即并隐式创建底层文件。
我完全同意这种行为,除非我有一个代码,只有在运行期间才能看到是否会产生任何数据。
因此,我想避免在没有数据发送给空文件时创建空文件(事务完整性:没有数据,文件系统上没有更改)。
我看到两种我不太喜欢的方法:
tellg()),如果流为空,则删除该文件。我不喜欢创建和删除文件(有时文件很多)并且remove操作本身承担了太多责任。std::stringstream,收集输出并std::ofstream仅在字符串流不为空的情况下创建和复制内容。好多了,但仍然需要临时内存分配,这可能很大。对此有更好的解决方案吗?我是否缺少一些想法?
以代码的形式:
#include <fstream>
int main()
{
std::ofstream ofs("file.txt");
// Some code that might or might not output to ofs
// Some other code that might or might not output to ofs
// Some more code that might or might not output to ofs
// It would be nice if file is not created if no data sent to ofs
}
Run Code Online (Sandbox Code Playgroud)
因此,代码可能包含许多执行输出的位置。
使用带有文件名的构造函数创建std::ofstream对象,打开文件。您可以通过仅在实际需要写入时提供文件名来解决此问题。open
#include <fstream>
int main()
{
std::ofstream ofs;
// determine whether you need to write
if (/*need_to_output*/) {
ofs.open("file.txt");
}
// write to ofs
}
Run Code Online (Sandbox Code Playgroud)
为了避免检查文件是否打开,请考虑这个简单的包装类
class lazy_open_ofstream {
public:
explicit lazy_open_ofstream(std::string filename) : _filename(std::move(filename)) {}
lazy_open_ofstream& operator<<(auto other) {
if (!ofs.is_open()) {
ofs.open(_filename);
}
ofs << other;
return *this;
}
private:
std::ofstream ofs;
std::string _filename;
};
Run Code Online (Sandbox Code Playgroud)
然后使用如下
lazy_open_ofstream ofs("file.txt");
// write to ofs or not
Run Code Online (Sandbox Code Playgroud)
注意:您可能需要operator<<根据需要进行调整。