[英]Write and read object of class into and from binary file
我尝试在 C++ 中将类的对象写入和读取到二进制文件中。 我不想单独写入数据成员,而是一次写入整个对象。 举个简单的例子:
class MyClass {
public:
int i;
MyClass(int n) : i(n) {}
MyClass() {}
void read(ifstream *in) { in->read((char *) this, sizeof(MyClass)); }
void write(ofstream *out){ out->write((char *) this, sizeof(MyClass));}
};
int main(int argc, char * argv[]) {
ofstream out("/tmp/output");
ifstream in("/tmp/output");
MyClass mm(3);
cout<< mm.i << endl;
mm.write(&out);
MyClass mm2(2);
cout<< mm2.i << endl;
mm2.read(&in);
cout<< mm2.i << endl;
return 0;
}
然而,运行输出显示应该写入二进制文件的 mm.i 的值未被读取并正确分配给 mm2.i
$ ./main
3
2
2
那么它有什么问题呢?
通常在二进制文件中写入或读取类的对象时,我应该注意什么?
数据正在缓冲,因此在您读取文件时它实际上并未到达文件。 由于您使用两个不同的对象来引用输入/输出文件,因此操作系统不知道它们之间的关系。
您需要刷新文件:
mm.write(&out);
out.flush()
或关闭文件(执行隐式刷新):
mm.write(&out);
out.close()
您还可以通过让对象超出范围来关闭文件:
int main()
{
myc mm(3);
{
ofstream out("/tmp/output");
mm.write(&out);
}
...
}
从多个角度来看,转储原始数据是一个糟糕的主意。 一旦您添加指针数据,这将变得更糟。
一个建议是使用Boost.Serialization ,它允许更强大的数据转储。
您的主要问题是由于 fstream 缓冲,该文件尚不包含内容。 关闭或刷新文件。
我会回应“你不应该这样做”。 如果您在上面的代码中打印出sizeof(myc)
它可能是 4,正如您所期望的那样......但是尝试将读取和写入更改为虚拟。 当我这样做时,它会打印出大小为 16。这 12 个字节是带有敏感值的内部数据——将它们保存出来然后读回它们就像期望一个指针值仍然是好的,如果你写了它并加载了它再说一遍。
如果你想绕过序列化并将 C++ 对象内存直接映射到磁盘,有一些方法可以破解。 但是涉及规则,它不适合胆小的人。 以POST++(C++ 的持久对象存储)为例。
我要补充一点,您没有检查fail()
或eof()
状态。 如果你知道,你就会知道你在滥用 fstream API。 再试一次:
void read(ifstream *in) {
in->read((char *) this, sizeof(myc));
if (in->fail())
cout << "read failed" << endl;
}
void write(ofstream *out){
out->write((char *) this, sizeof(myc));
if (out->fail())
cout << "write failed" << endl;
}
...看看会发生什么。
我的 C++ 非常生疏,而且未经充分测试,但您可能想看看序列化和反序列化。 常问问题
我使用output.write((char*)&obj, sizeof(obj))
做了类似的事情,obj 是你的类的一个实例。 如果您想将数据写入对象内部,您可能想要循环此操作,通常情况下是这样,因为您需要成员可读,对吗?
使用 read 功能阅读也是如此。 但是,如果您要动态分配这些数据,则需要处理它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.