繁体   English   中英

在二进制文件中写入和读取类的对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM