LVGL-C 实现一个文件持久性缓存,用于存储配置相关数据

实现功能描述:

基于linux嵌入式平台开发App,在未移植数据库的情况下,文件存储是一个不错的持久性数据存储手段。

创建代码文件:configcache.h configcache.c

1. 数据结构的结构体封装

点击查看代码

    // 配置信息结构
    typedef struct
    {
        char *key;
        char *value;
    } ConfigItem;

2. 相关函数申明

点击查看代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

//相关宏
#define CONFIG_FILE_NAME "config.txt"
#define LANGUAGE_KEY "language_key"
#define TEMP_KEY "temp_key"
    
    /*数据结构...*/
    //默认数据
    static ConfigItem configArr[] = {
        {LANGUAGE_KEY, "1"}, // 默认英语
        {TEMP_KEY, "58"},
    };
    static int mConfigItemSize; // 配置信息数量
    //判断空文件
    int isFileEmpty(const char *filename);
    //初始化配置
    void initConfig(const char *filename);
    // 读取文件
    void readConfig(const char *filename);
    // 获取配置项
    ConfigItem getConfigItem(char *key);
    // 更新数据
    void setConfigItem(char *key, char *value);
    // 保存文件
    int saveConfig();

3. 相关函数定义

点击查看代码

#include "configcache.h"

int isFileEmpty(const char *filename)
{
    struct stat filestat;
    if (stat(filename, &filestat) < 0)
    {
        return -1;
    }
    return filestat.st_size == 0;
}

// 初始化配置文件
void initConfig(const char *filename)
{
    int isEmpty = isFileEmpty(filename);
    PRINT("initConfig  = [%d]\n", isEmpty);
    if (1 == isEmpty || -1 == isEmpty)
    {
        FILE *file = fopen(filename, "w+");
        if (file != NULL)
        {
            char line[100];
            int length = sizeof(configArr) / sizeof(configArr[0]);
            for (int i = 0; i < length; i++)
            {
                fprintf(file, "%s=%s\n", configArr[i].key, configArr[i].value);
                PRINT("fprintf  = [%d]\n", i);
            }
            fflush(file); // 强制刷新缓冲区来将数据写入到文件
            fclose(file);
        }
        else
        {
            perror("Error opening file");
        }
    }
}

/**
 * 读取配置文件
 *
 * @param filename 配置文件的名称
 *
 * @return 返回配置数组
 */
void readConfig(const char *filename)
{
    int count = 0;
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        perror("Error opening file");
        return NULL;
    }
    char line[100];
    while (fgets(line, sizeof(line), file) != NULL)
    {

        // 分割行,获取键和值
        char *delim = strchr(line, '=');
        if (delim == NULL)
            continue;

        *delim = '\0'; // 在键和值之间插入空字符
        configArr[count].key = strdup(line);
        configArr[count].value = strdup(delim + 1);
        PRINT("key %s \n", configArr[count].key);
        PRINT("value %s \n", configArr[count].value);
        count++;
    }

    if (file != NULL)
    {
        fclose(file);
    }
    mConfigItemSize = sizeof(configArr) / sizeof(configArr[0]);
    PRINT("readConfig count = %d\n", count);
    PRINT("readConfig items length = %d\n", mConfigItemSize);
}

ConfigItem getConfigItem(char *key)
{
    ConfigItem item;
    for (int i = 0; i < mConfigItemSize; i++)
    {
        if (strcmp(configArr[i].key, key) == 0)
        {
            item.key = strdup(configArr[i].key);
            item.value = strdup(configArr[i].value);
        }
    }
    return item;
}

// 更新数据
void setConfigItem(char *key, char *value)
{
    int saveStatus = 0; // 0:不存在的数据无需保存,1:保存修改的数据
    for (int i = 0; i < mConfigItemSize; i++)
    {
        if (strcmp(configArr[i].key, key) == 0)
        {
            free(configArr[i].value);
            configArr[i].value = strdup(value);
            PRINT("setConfigItem  %s = %s \n", key, value);
            saveStatus = 1;
        }
    }
    if (saveStatus)
    {
        saveConfig();
    }
}

/**
 * 保存配置项到指定文件
 *
 * @param filename 配置文件的名称
 * @param items 配置项的数组,每个配置项包含具体配置信息
 *
 * @return 返回保存操作的结果,0表示成功,非0表示失败
 */
int saveConfig()
{
    FILE *file = fopen(CONFIG_FILE_NAME, "w");
    if (file == NULL)
    {
        perror("Error opening file");
        return -1;
    }
    for (int i = 0; i < mConfigItemSize; i++)
    {
        fprintf(file, "%s=%s\n", configArr[i].key, configArr[i].value);
        PRINT("saveConfig fprintf  :  %s=%s\n", configArr[i].key, configArr[i].value);
    }
    fflush(file);
    if (file != NULL)
    {
        fclose(file);
    }

    return 0;
}

4. 初始化,函数调用示例:

点击查看代码

    // 初始化配置(持久化)缓存
    initConfig(CONFIG_FILE_NAME);
    readConfig(CONFIG_FILE_NAME);
    // 获取当前语言
    PRINT("current_language = %d \n\n", getConfigItem(LANGUAGE_KEY).value);

5. 附加代码中的宏打印(configcache.h顶部申明)

点击查看代码

#define PRINT_SWITCH 1 // 打印宏
#if PRINT_SWITCH
#define PRINT(format, ...) printf(format, ##__VA_ARGS__)
#else
#define PRINT(format, ...)
#endif

来源链接:https://www.cnblogs.com/MrMoney/p/18643355

请登录后发表评论

    没有回复内容