[英]How to write an object to file in C++
我有一个带有几个文本字符串作为成员的对象。 我想一次性将这个对象写入文件,而不是将每个字符串写入文件。 我怎样才能做到这一点?
您可以覆盖operator>>
和operator<<
以读取/写入流。
带有一些值的示例Entry struct
:
struct Entry2
{
string original;
string currency;
Entry2() {}
Entry2(string& in);
Entry2(string& original, string& currency)
: original(original), currency(currency)
{}
};
istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);
执行:
using namespace std;
istream& operator>>(istream& is, Entry2& en)
{
is >> en.original;
is >> en.currency;
return is;
}
ostream& operator<<(ostream& os, const Entry2& en)
{
os << en.original << " " << en.currency;
return os;
}
然后打开文件流,并为您调用的每个对象:
ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read:
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();
或输出:
Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();
或者,如果您想使用流read
和write
那么您只需替换operator
实现中的相关代码。
当变量在struct / class中是私有的时,你需要将operator
s声明为friend方法。
您可以实现任何您喜欢的格式/分隔符。 当你的字符串包含空格时,使用getline()接受字符串和流而不是>>
因为operator>>
默认使用空格作为分隔符。 取决于你的分隔符。
它被称为序列化。 SO上有许多序列化线程。
boost中还包含一个很好的序列化库。
http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html
基本上你可以做到
myFile<<myObject
和
myFile>>myObject
与boost序列化。
如果你有:
struct A {
char a[30], b[25], c[15];
int x;
}
然后你可以用write(fh,ptr,sizeof(struct a))来编写它。
当然,这不是可移植的(因为我们没有保存“int”的结尾或大小,但这对你来说可能不是问题。
如果你有:
struct A {
char *a, *b, *c;
int d;
}
然后你不打算写这个对象; 你想要序列化它。 最好的办法是查看Boost库并使用它们的序列化例程,因为在没有反射的语言中它不是一个简单的问题。
实际上并不是一种简单的方法,它毕竟是C ++,而不是PHP或JavaScript。
http://www.parashift.com/c++-faq-lite/serialization.html
Boost还有一些库: http : //www.boost.org/doc/libs/release/libs/serialization ...就像Tronic已经提到过:)
更好的方法是单独编写每个字段以及字符串长度。
作为替代方法,您可以创建一个char
数组(或std::vector<char>
)并将所有成员写入缓冲区,然后将缓冲区写入输出。
潜在的棘手是允许编译器在类或结构中的成员之间插入填充。 使用memcpy
或std::copy
将导致填充字节写入输出。
请记住,您需要编写字符串长度和内容或内容后跟一些终止字符。
其他人会建议查看Boost序列化库。
不幸的是,这通常不太可能。 如果您的结构只包含纯数据(没有指针或复杂对象),您可以将它存储为一个块,但如果可移植性是一个问题,必须小心。 填充,数据类型大小和endianess问题使这成为问题。
您可以使用Boost.Serialization来最小化正确的可移植和可版本化的searialization所需的代码量。
假设您的目标如上所述,只需调用write()或fwrite()或其他任何东西来写出对象,您首先需要将字符串和其他对象数据复制到单个连续的内存块中。 然后你可以通过一次调用写出()该内存块。 或者,如果您的平台上有该调用,则可以通过调用writev()来执行向量写入。
也就是说,通过减少写入调用次数,您可能不会获得太多收益。 特别是如果你已经使用fwrite()或类似的,那么C库已经为你做了缓冲,所以无论如何多个小调用的成本是最小的。 不要让自己经历许多额外的痛苦和代码复杂性,除非它实际上会做一些好事......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.