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

时间:2017-10-26 07:48:37

标签: c++ serialization file-io binary-data

我想知道写作时会发生什么:

object.write((char*)&class_object, sizeof(class_object));
// or
object.read((char*)&class_object, sizeof(class_object));

从我到目前为止读到的内容,class_object被转换为指针。但我不知道它如何设法将对象携带的数据转换为二进制。二进制文件实际代表什么?

我是初学者。

修改

请您解释一下我们编写上述代码时会发生什么?我的意思是,当我们写(char *)* S时,实际发生了什么,比如哪里S是我声明的类的对象?

2 个答案:

答案 0 :(得分:1)

实际上,至少在classstruct不是undefined behavior(普通旧数据)时,您的代码将无效并可能会产生POD )并包含指针或虚函数(因此有一些vtable)。

二进制文件将包含对象的位表示,这不是portable到另一台计算机,甚至不是运行相同程序的另一个进程(特别是因为ASLR),除非你的对象是个POD。

另见this answer一个非常相似的问题。

你可能想要一些serialization。由于磁盘和文件访问比CPU慢很多(比十万个慢),因此使用一些更便携的数据表示通常是明智之举。实际上,您应该考虑一些文本表示,例如JSONXMLYAML等等...... jsoncpp之类的库非常易于使用,您需要编写一些代码才能将对象转换为某些内容JSON,并从JSON创建一些对象。

还要记住,数据通常比代码更昂贵,更珍贵。关键是你经常需要一些旧版本的数据(由程序的先前版本编写)可以被更新版本的程序读取。这可能不是微不足道的(例如,如果您添加或更改了class中某些字段的类型)。

您还可以阅读dynamic software updating。这是一个有趣的研究课题。请注意databases

另请阅读parsing技术,特别是recursive descent parsers。它们是相关的。

答案 1 :(得分:1)

想象一下,如果将类转换为char指针,则类实例只是在RAM中休息的一些内存块:

SomeClass someClassInstance;
char* data = reinterpret_cast<char*>(&someClassInstance);

它将指向您内存中的相同数据,但它将被视为程序中的字节数组。

如果您将其转换回来:

SomeClass* instance = reinterpret_cast<SomeClass*>(data);

它将再次被视为班级。

因此,为了将您的类编写到文件中并稍后重新构建它,您可以将data写入某个大小为sizeof(SomeClass)的文件,然后读取该文件并转换原始文件字节到类实例。

但是,请注意,如果您的课程为POD(普通旧数据),您只能这样做!