想问下,C++,怎么把一个对象的内容保存在磁盘的文件里呢?

我在用qt,比方说我设计了一个类.

class F
{
    QString str;
    int a;
    QDate date;
};

然后我的程序运作时需要一个这个类的数组,比方说

vector<F>v;

这么个数组.
现在我希望,我能把这个数组内的F对象的内容写到磁盘上,这样我下次还能再用这份数据.
但我总觉得自己的实现非常笨拙,我是把QDate类直接当作3个数字,QString当作一个字符串,用^当作成员之间的分隔符,用换行符当作元素之间的分隔符,打印出一个文件...
感觉很笨拙,想问下有什么高明的手法吗?

阅读 1.4k
2 个回答

我觉得你是在说对象的序列化和反序列化。序列化就是把对象转成字符流或字节流以便传输或存储,反序列化就是从数据里恢复对象。
在java里我们有专门的对象序列化接口,实现这个接口就可以将对象序列化成字节流写到文件里,然后也可以通过文件读取字节流再把它转成对象。
除了java特有的序列化,我觉得可能很多语言包括python和c++等都可以用json作为序列化方案,就是把对象写到json文件里面,这样也有助于在异构的程序间传递数据。json文件的格式很好理解,比如你的对象就可以写成

{
  "str": "abcdefg",
  "a": 123456,
  "date": "2023-11-15"
}

在json里表示列表可以用中括号[],比如表示一个你的对象的列表可以是

[{
  "str": "abcdefg",
  "a": 123456,
  "date": "2023-11-15"
},
{
  "str": "vwxyz",
  "a": 98765,
  "date": "2023-11-14"
}]

我觉得c++大概率是有json序列化和反序列化库的,可以试着找一下?

新手上路,请多包涵

我之前在Liunx环境下用C中的mmap()尝试过对结构体的保存,以下代码可供参考

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

#define handle_error(msg)   \
    do                      \
    {                       \
        perror(msg);        \
        exit(EXIT_FAILURE); \
    } while (0)

typedef unsigned short U16;

struct test
{
    unsigned int value;
    unsigned char char1;
    unsigned char char2;
    unsigned char char3;
    unsigned char char4;
    unsigned char char5;//观察内存对齐
};

int Struct_save(char *pathName, void *data, size_t size)
{
    int fd = 0;
    void *start = NULL;
    struct stat buf = {0};

    fd = open(pathName, O_RDWR | O_CREAT);
    printf("open %s ...\n", pathName);
    ftruncate(fd, size);

    if (fstat(fd, &buf) < 0)
    {
        printf("get file state error:%d\n", errno);
        close(fd);
        return -1;
    }
    start = mmap(NULL, buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    if (MAP_FAILED == start)
    {
        handle_error("mmap");
    }

    printf("copying data to start %ld bytes\n", size);
    memcpy(start, data, size);

    munmap(start, buf.st_size);
    close(fd);
}
int Struct_load(char *pathName, void *data, size_t size)
{

    int fd = 0;
    void *start = NULL;
    struct stat buf = {0};

    printf("open %s ...\n", pathName);
    fd = open(pathName, O_RDWR);

    if (fstat(fd, &buf) < 0)
    {
        printf("get file state error:%d\n", errno);
        close(fd);
        return -1;
    }

    start = mmap(NULL, buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (MAP_FAILED == start)
    {
        handle_error("mmap");
    }

    printf("copying start to data %ld bytes\n", size);
    memcpy(data, start, size);

    munmap(start, buf.st_size);
    close(fd);
}
int main(int *argc, const char **argv)
{
    struct test save = {0};
    struct test load = {0};

    save.value = 0x01020304;

    save.char1 = 0x71;
    save.char2 = 0x72;
    save.char3 = 0x73;
    save.char4 = 0x74;
    save.char5 = 0x75;

    printf("Saving value=0x%x char1=0x%x char2=0x%x char3=0x%x char4=0x%x char5=0x%x\n", save.value,save.char1,save.char2,save.char3,save.char4, save.char5);
    Struct_save("temp.save", &save, sizeof(save));

    Struct_load("temp.save", &load, sizeof(load));

    printf("Loading value=0x%x char1=0x%x char2=0x%x char3=0x%x char4=0x%x char5=0x%x\n", load.value,load.char1,load.char2,load.char3,load.char4,load.char5);

    // for (int i = 0; i < sizeof(temp.value); i++)
    // {
    //     printf("%x ",((unsigned char * )&temp.value)[i]);
    // }

    exit(EXIT_SUCCESS);

    return 0;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题