Search code examples
c++fstream

What's the most simple way to read and write data from a struct to and from a file in c++ without serialization library?


I am writing a program to that regularly stores and reads structs in the form below.

struct Node {
    int leftChild = 0;
    int rightChild = 0;
    std::string value;
    int count = 1;
    int balanceFactor = 0;
};

How would I read and write nodes to a file? I would like to use the fstream class with seekg and seekp to do the serialization manually but I'm not sure how it works based off of the documentation and am struggling with finding decent examples.

[edit] specified that i do not want to use a serialization library.


Solution

  • To serialize objects, you will need to stick to the concept that the object is writing its members to the stream and reading members from the stream. Also, member objects should write themselves to the stream (as well as read).

    I implemented a scheme using three member functions, and a buffer:

    void load_from_buffer(uint8_t * & buffer_pointer);  
    void store_to_buffer(uint8_t * & buffer_pointer) const;  
    unsigned int size_on_stream() const;  
    

    The size_on_stream would be called first in order to determine the buffer size for the object (or how much space it occupied in the buffer).

    The load_from_buffer function loads the object's members from a buffer using the given pointer. The function also increments the pointer appropriately.

    The store_to_buffer function stores the objects's members to a buffer using the given pointer. The function also increments the pointer appropriately.

    This can be applied to POD types by using templates and template specializations.

    These functions also allow you to pack the output into the buffer, and load from a packed format.

    The reason for I/O to the buffer is so you can use the more efficient block stream methods, such as write and read.

    Edit 1: Writing a node to a stream
    The problem with writing or serializing a node (such a linked list or tree node) is that pointers don't translate to a file. There is no guarantee that the OS will place your program in the same memory location or give you the same area of memory each time.

    You have two options: 1) Only store the data. 2) Convert the pointers to file offsets. Option 2) is very complicated as it may require repositioning the file pointer because file offsets may not be known ahead of time.

    Also, be aware of variable length records like strings. You can't directly write a string object to a file. Unless you use a fixed string width, the string size will change. You will either need to prefix the string with the string length (preferred) or use some kind of terminating character, such as '\0'. The string length first is preferred because you don't have to search for the end of the string; you can use a block read to read in the text.