C语言redis存储结构体

更多技术干货尽在公众号“系统编程语言”。

在 C 语言中使用 Redis 存储复杂结构体可以通过序列化和反序列化来实现。Redis 本身支持字符串、哈希、列表、集合等数据类型,但这些类型主要用于存储简单的数据。为了存储复杂的结构体,通常需要将结构体序列化为字符串或 JSON 格式,然后再存储到 Redis 中。

以下是一个示例,展示如何使用 C 语言和 Redis 存储和检索复杂结构体。

1. 安装 Redis 和 Redis C 客户端

首先,确保你已经安装了 Redis 服务器和 Redis C 客户端库(如 hiredis)。

sudo apt-get update
sudo apt-get install redis-server
sudo apt-get install libhiredis-dev

2. 定义复杂结构体

假设我们有一个复杂的结构体,包含嵌套的结构体和数组。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>

typedef struct {
    char name[50];
    int age;
} Person;

typedef struct {
    char title[100];
    Person* members;
    int member_count;
} Team;

3. 序列化和反序列化

我们需要编写函数来将 Team 结构体序列化为字符串,并从字符串反序列化回 Team 结构体。

#include <jansson.h>  // JSON 库

char* serialize_team(Team* team) {
    json_t *root, *members_array, *member_obj;
    json_error_t error;

    root = json_object();
    members_array = json_array();

    json_object_set_new(root, "title", json_string(team->title));

    for (int i = 0; i < team->member_count; i++) {
        member_obj = json_object();
        json_object_set_new(member_obj, "name", json_string(team->members[i].name));
        json_object_set_new(member_obj, "age", json_integer(team->members[i].age));
        json_array_append_new(members_array, member_obj);
    }

    json_object_set_new(root, "members", members_array);

    char *json_str = json_dumps(root, JSON_COMPACT);
    json_decref(root);

    return json_str;
}

Team* deserialize_team(const char* json_str) {
    json_error_t error;
    json_t *root, *members_array, *member_obj;
    Team *team = (Team*)malloc(sizeof(Team));

    root = json_loads(json_str, 0, &error);
    if (!root) {
        fprintf(stderr, "Error parsing JSON: %s\n", error.text);
        return NULL;
    }

    const char *title = json_string_value(json_object_get(root, "title"));
    strncpy(team->title, title, sizeof(team->title) - 1);

    members_array = json_array_get(root, "members");
    team->member_count = json_array_size(members_array);
    team->members = (Person*)malloc(team->member_count * sizeof(Person));

    for (int i = 0; i < team->member_count; i++) {
        member_obj = json_array_get(members_array, i);
        const char *name = json_string_value(json_object_get(member_obj, "name"));
        int age = json_integer_value(json_object_get(member_obj, "age"));

        strncpy(team->members[i].name, name, sizeof(team->members[i].name) - 1);
        team->members[i].age = age;
    }

    json_decref(root);
    return team;
}

4. 存储和检索复杂结构体

使用 hiredis 库将序列化后的字符串存储到 Redis 中,并从 Redis 中检索并反序列化回 Team 结构体。

int main() {
    redisContext *c = redisConnect("127.0.0.1", 6379);
    if (c == NULL || c->err) {
        if (c) {
            printf("Error: %s\n", c->errstr);
            redisFree(c);
        } else {
            printf("Can't allocate redis context\n");
        }
        return 1;
    }

    // 创建一个 Team 结构体
    Team team;
    strcpy(team.title, "Development Team");
    team.member_count = 2;
    team.members = (Person*)malloc(team.member_count * sizeof(Person));

    strcpy(team.members[0].name, "Alice");
    team.members[0].age = 30;

    strcpy(team.members[1].name, "Bob");
    team.members[1].age = 35;

    // 序列化 Team 结构体
    char *json_str = serialize_team(&team);

    // 存储到 Redis
    redisReply *reply = (redisReply*)redisCommand(c, "SET team_data %s", json_str);
    if (reply->type == REDIS_REPLY_ERROR) {
        printf("Error setting data: %s\n", reply->str);
    } else {
        printf("Data stored successfully\n");
    }
    freeReplyObject(reply);
    free(json_str);

    // 从 Redis 中检索数据
    reply = (redisReply*)redisCommand(c, "GET team_data");
    if (reply->type == REDIS_REPLY_STRING) {
        Team *retrieved_team = deserialize_team(reply->str);
        if (retrieved_team) {
            printf("Retrieved Team Title: %s\n", retrieved_team->title);
            for (int i = 0; i < retrieved_team->member_count; i++) {
                printf("Member %d: Name=%s, Age=%d\n", i, retrieved_team->members[i].name, retrieved_team->members[i].age);
            }
            free(retrieved_team->members);
            free(retrieved_team);
        }
    } else {
        printf("Error retrieving data\n");
    }
    freeReplyObject(reply);

    // 清理
    free(team.members);
    redisFree(c);

    return 0;
}

5. 编译和运行

确保你已经安装了 hiredis 和 jansson 库,然后编译并运行程序。

gcc -o redis_example redis_example.c -lhiredis -ljansson
./redis_example

总结

通过将复杂结构体序列化为 JSON 字符串,可以方便地使用 Redis 存储和检索这些结构体。hiredis 库用于与 Redis 服务器进行通信,而 jansson 库用于处理 JSON 序列化和反序列化。这种方法不仅简单,而且灵活,适用于各种复杂的结构体。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GarenJian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值