简体   繁体   中英

Read and write binary file with reinterpreter_cast

For example if i have a class named Obj and an Obj named obj1 . When I want to write in a binary file with reinterpret_cast I open that file in binary mode and then,

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

where outstream is a ifstream.

When i want to read from that file,

instream.read( reinterpret_cast<char *>(&obj1), sizeof(obj1) )

What happened. It read the representation of obj1 in binary and convert to obj1 or how this is working. When I write I understand that it interpret obj1 an one byte but when I read I don't understand what happens.

When you re-interpret a pointer to object as a pointer to char , you write the in-memory representation of the object itself. This includes

  • All pointers inside the object. For classes with virtual members this may include a pointer to vtable, depending on the implementation
  • All padding between members,
  • All data members, in the endianness of your hardware.

This write does not include any part of your object pointed to by pointers.

Moreover, when you read an object with pointers back into memory, the values in these pointers will be garbage. If you dereference any of it, you get undefined behavior.

This makes the technique applicable only to plain old data (POD) objects, ie primitives and structs/classes composed of primitives and other POD objects. In addition, the technique is not applicable when you need cross-hardware compatibility.

Say, an object of class Obj takes up 4 bytes in memory.

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

A char , normally, takes up 1 byte. So when you do the reinterpret_cast your object will be treated as the 4 separate bytes (an array of characters, so to speak).

When you serialize your object in this way you will store the raw bytes 0 through 3 , and your file will contain the 4 bytes 0xFF 0xFF 0xFF 0xFF . Bottom line you're copying the raw bytes into a file.

Deserialization is just as simple, you have a placeholder Obj to be read into and then the same bytes in the file will overwrite the object.


There's a caveat. This sort of serialization will only work on POD types or structures with simple data members. Like this,

struct Foo {
    int bar1;
    float bar2;
};

It won't work on things like std::vector , or std::list , etc. In general it won't work on pointers, because if you store the raw value (address) the pointer contains it will be meaningless in the next time you run your program and read this address. Your object will contain an invalid pointer after deserializing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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