c++bufferreadfile

How to write a struct to file in C++ and read the file?


I have a struct and write it to a file using the write().

struct PointFull {
    double lat;
    double lon;
};

PointFull item;
void* buffer = malloc(sizeof (item));
int fd = open("output", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
if (fd < 0) {
    printf("Error opening file\n");
    return 1;
}
memcpy(buffer, &item, sizeof (item));
write(fd2, 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(100);
read(fd2, bufferRead,100);

At the moment, I have bufferRead but I dont know how to read buffer to insert data to struct?


Solution

    1. You'd rather allocate a buffer of size sizeof(PointFull). Because if size of struct would ever be changed and become bigger than your hardcoded size, then you going to get a bug.

    2. Use a local buffer unless you really need to use a dynamic memory. I assume that in your code you don't really need an allocation. It's just that you may easily forget to deallocate the memory, whereas buffer deleted automagically when a function returns.

    int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
    if (fd2 < 0) {
        printf("Error opening file\n");
        return 1;
    }
    char bufferRead[sizeof(PointFull)];
    read(fd2, bufferRead, sizeof(bufferRead));
    //Now as you've read it, just cast the memory to struct, and assign it
    item = *reinterpret_cast<PointFull*>(bufferRead);
    //okay, now item holds the file content, you no longer need the buffer
    

    Also note: your struct might be aligned by inserting a padding. Although I don't think it would be the case with PointFull, anyway, when you need to serialize structures like here, you'd better declare it with #pragma pack to not allow the padding. E.g.:

    #pragma pack(push, 1) // exact fit - no padding
    struct PointFull {
        double lat;
        double lon;
    };
    #pragma pack(pop) //back to whatever the previous packing mode was