使用reinterpreter_cast读取和写入二进制文件

时间:2015-09-19 12:23:06

标签: c++ file binary reinterpret-cast

例如,如果我有一个名为Obj的类和一个名为Obj的{​​{1}}。当我想用obj1写入二进制文件时,我以二进制模式打开该文件,然后

reinterpret_cast

其中outstream是ifstream。

当我想从该文件中读取时,

outstream.write( reinterpret_cast<const char *>(&obj1), sizeof(obj1) )

发生了什么事。它以二进制形式读取instream.read( reinterpret_cast<char *>(&obj1), sizeof(obj1) ) 的表示形式并转换为obj1或其工作原理。当我写作时,我明白它会解释obj1一个字节,但是当我读到时,我不明白会发生什么。

2 个答案:

答案 0 :(得分:3)

当您将指向对象的指针重新解释为指向char的指针时,您可以编写对象本身的内存中表示形式。这包括

  • 对象内的所有指针。对于具有虚拟成员的类,这可能包含指向vtable的指针,具体取决于实现
  • 成员之间的所有填充,
  • 所有数据成员,以硬件的字节顺序显示。

此写操作不包括指针所指向的对象的任何部分。

此外,当您将带有指针的对象读回内存时,这些指针中的值将是垃圾。如果你取消引用任何一个,你会得到未定义的行为。

这使得该技术仅适用于普通旧数据(POD)对象,即由基元和其他POD对象组成的基元和结构/类。此外,当您需要跨硬件兼容性时,该技术不适用。

答案 1 :(得分:2)

比如说,类Obj的对象在内存中占用4个字节。

[OBJ] = [0][1][2][3]
      = FF FF FF FF  //(for example, all bytes contain 0xFF)

char通常占用1个字节。因此,当您执行reinterpret_cast时,您的对象将被视为作为4个单独的字节(可以这么说是一个字符数组)。

以这种方式序列化对象时,您将原始字节0存储到3,并且您的文件将包含4字节0xFF 0xFF 0xFF 0xFF。您将原始字节复制到文件中的底线。

反序列化就是这么简单,你有一个占位符Obj被读入,然后文件中的相同字节将覆盖该对象。

有一个警告。这种序列化仅适用于具有简单数据成员的POD类型或结构。像这样,

struct Foo {
    int bar1;
    float bar2;
};

它不适用于std::vectorstd::list等内容。 一般情况下,它不适用于指针,因为如果存储指针所包含的原始值(地址),则在下次运行程序并读取此地址时,它将毫无意义。反序列化后,您的对象将包含无效指针。