Search code examples
c++bufferreadfilewritefile

How to read and write many objects (or any data) to a buffer?


I am writing a program to save some object (struct) to a buffer. I don't have experiment to write many objects to buffer and read these objects from the buffer. Any help would be appreciated. My code can write one item to object and I want write many objects to the buffer

struct PointFull {
    double lat;
    double lon;
};

PointFull item1;
PointFull item2;
PointFull item3;
PointFull item4;
PointFull item5;

void* buffer = malloc(sizeof (PointFull));
int fd = open("output", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
if (fd < 0) {
    printf("Error opening file\n");
    return 1;
}

//The below function can write only one item to buffer. How to write 5 item (from item1 to item5) to the buffer
//memcpy(buffer, &item1, sizeof (item));

write(fd, buffer, sizeof (item));

Now I have a file named "output" in hard disk and then I want read the file to test data.

    int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
if (fd2 < 0) {
    printf("Error opening file\n");
    return 1;
}
void* bufferRead;
bufferRead = malloc(5* sizeof (PointFull));
read(fd2, bufferRead,sizeof (PointFull));

At the moment, I have bufferRead contain 5 items but I dont know how to read buffer to insert data to struct??? Plz help me!


Solution

  • Well what you want to do is serialization. Say you have such structure:

    struct PointFull {
        int lat;
        int lon;
    };
    

    and also

    PointFull item1, item2;
    

    The way you serialize it to buffer is:

    unsigned char arr[20] = {0};
    memcpy(arr, &item1.lat, sizeof(int));
    memcpy(&arr[1 * sizeof(int)], &item1.lon, sizeof(int));
    memcpy(&arr[2 * sizeof(int)], &item2.lat, sizeof(int));
    memcpy(&arr[3 * sizeof(int)], &item2.lon, sizeof(int));
    

    I am serializing like this because it is not good idea to directly write the structure like you suggest because of padding problems. The structures may have paddings and they may differ per system.

    Now, you have the byte array (which contains two PointFull objects - for more objects you would follow similar approach) and you can use it in your write:

    write(fd, arr, 20);
    

    After reading the byte array you could reconstruct point objects by using similar memcpy calls like above (just destination would be the point object members now). But the problem with this is that integer serialization in binary is not portable (and floats moreover) - on different systems integers may have different size, different endianness. With floats additionally their representation may differ.

    Anyway there is one way how to encode floats in binary here - check pack754 (and similar unpack) function. If you use that function for serializing floats in byte array and serialize each float separately like in this answer, then maybe you will be fine.

    PS. here is post which explains serialization (for float encoding part you can use link in my answer).