读写内存数据

samuelbrody1249

在下面的示例中,我采用一个结构,该结构在内存中占用32个字节,并将其写入文件并读回-即,将数据序列化为二进制格式:

#include <stdio.h>

typedef struct _Person {
    char   name[20];
    int    age;
    double weight;
} Person;

int main(void)
{

    Person tom = (Person) {.name="Tom", .age=20, .weight=125.0};

    // write the struct to a binary file
    FILE *fout = fopen("person.b", "wb");
    fwrite(&tom, sizeof tom, 1, fout);
    fclose(fout);

    // read the binary data and set the person to that
    Person unknown;
    FILE *fin = fopen("person.b", "rb");
    fread(&unknown, sizeof unknown, 1, fin);
    fclose(fin);

    // confirm all looks ok
    printf("{name=%s, age=%d, weight=%f}", unknown.name, unknown.age, unknown.weight);

}

但是请注意,这些都是堆栈上的所有值,并且不涉及指针/间接寻址。例如,当涉及多个指针,多个变量可能指向同一内存位置等时,如何将数据序列化到文件中?这有效地是协议缓冲区的作用吗?

约书亚记

好的,所以您想要一个二进制文件。我很久以前就这样做。没关系。当您转移到另一个平台或咬紧牙关时,它只会断裂。我正在教旧方法,因为这是一个很好的起点。现在,较新的方法很流行,因为它们在更改平台或位时会一直起作用。

当将记录写入文件时,我将使用如下结构:

typedef struct _Person {
    char   name[20];
    int    age;
    double weight;
} Person;

typedef struct _Thing {
    char name[20];
};

typedef struct _Owner {
    int personId;
    int thingId;
} Owner;

查看Owner结构如何具有Id成员。这些只是其他结构数组的索引。

这些可以一个接一个地写到一个文件中,通常以直接写的单个整数作为前缀,该整数表示每种记录的数量。读者只是分配一个结构数组,其malloc大小足以容纳它们。随着我们在内存中添加更多项目,我们使用来调整数组的大小realloc我们也可以(并且应该)标记为删除(例如,将name的第一个字符设置为0)并在以后重新使用记录。

作者看起来像这样:

void writeall(FILE *h, Person *allPeople, int nPeople, Thing *allThings, int nThings, Owner *allOwners, int nOwners)
{
    // Error checking omitted for brevity
    fwrite(&nPeople, sizeof(nPeople), 1, h);
    fwrite(allPeople, sizeof(*allPeople), nPeople, h);
    fwrite(&nThings, sizeof(nThings), 1, h);
    fwrite(allThings, sizeof(*allThings), nThings, h);
    fwrite(&nOwners, sizeof(nOwners), 1, h);
    fwrite(allOwners, sizeof(*allOwners), nOwners, h);
}

读者依次如下所示:

int writeall(FILE *h, Person **allPeople, int *nPeople, int *aPeople, Thing **allThings, int *nThings, int *aThings, Owner **allOwners, int *nOwners, int *aOwners)
{
    *aPeople = 0; // Don't crash on bad read
    *aThigns = 0;
    *aOwners = 0;
    *allPeople = NULL;
    *allThings = NULL;
    *allOwners = NULL;

    if (1 != fread(nPeople, sizeof(*nPeople), 1, h)) return 0;
    *allPeople = malloc(sizeof(**allPeople) * *nPeople);
    if (!allPeople) return 0; // OOM
    *aPeople = *nPeople;
    if (*nPeople != fread(*allPeople, sizeof(**allPeople), nPeople, h)) return 0;

    if (1 != fread(nThings, sizeof(*nThings), 1, h)) return 0;
    *allThings = malloc(sizeof(**allThings) * *nThings);
    if (!allThings) return 0; // OOM
    *aThings = *nThings;
    if (*nThings != fread(*allThings, sizeof(**allThings), nThings, h)) return 0;

    if (1 != fread(nOwners, sizeof(*nOwners), 1, h)) return 0;
    *allOwners = malloc(sizeof(**allOwners) * *nOwners);
    if (!allOwners) return 0; // OOM
    *aOwners = *nOwners;
    if (*nOwners != fread(*allOwners, sizeof(**allOwners), nOwners, h)) return 0;

    return 1;
}

有一种古老的技术可以将堆竞技场直接写入磁盘,然后再次读取。我建议不要使用它,也不要在磁盘上存储指针。这样就存在安全噩梦。

当内存不足时,我会谈到如何使用块分配和链接块来部分动态更新磁盘上的记录。但是现在对于您将在此级别遇到的问题,我说不要打扰,只需将整个内容读入RAM并再次写回即可。最终,您将学习数据库,数据库将为您处理这些东西。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++,读写内存,

来自分类Dev

内存读写字节

来自分类Dev

优化内存读写的长期运行

来自分类Dev

用GSON读写数据

来自分类Dev

用GSON读写数据

来自分类Dev

如何使用sigsegv捕获内存读写?

来自分类Dev

读写整数数组到共享内存

来自分类Dev

LLDB内存或运行时读写

来自分类Dev

读写整数数组到共享内存

来自分类Dev

读写大文件 C++(内存过载)

来自分类Dev

SparkR读写数据帧问题

来自分类Dev

如何使用内存映射文件C#读写文件?

来自分类Dev

IO读写操作的TPL Dataflow实现中的内存问题

来自分类Dev

为什么我获得未分配内存的读写权限?

来自分类Dev

使用Apache.POI读写Excel的Java内存问题

来自分类Dev

持久性内存缓存策略,可读写

来自分类Dev

为什么我要获得未分配内存的读写权限?

来自分类Dev

增强内存映射文件:读写访问

来自分类Dev

如何使用JakeWharton的DiskLruCache正确读写数据?

来自分类Dev

读写文件中的任何数据结构?

来自分类Dev

如何使用JakeWharton的DiskLruCache正确读写数据?

来自分类Dev

优化mysql表schema读写数据

来自分类Dev

Firebase 实时数据库读写数据协议与android

来自分类Dev

通过SQL进行数据库读写冲突

来自分类Dev

如何读写Rebol结构的数据文件(不包含代码)?

来自分类Dev

Mongo用户权限,可读写任何数据库

来自分类Dev

使用Arduino在SD上读写二进制数据

来自分类Dev

具有读写权限将数据卷挂载到Docker

来自分类Dev

在串行端口(到intel galileo)的Windows中读写数据