首页 > 其他分享 >LVGL-C 实现一个文件持久性缓存,用于存储配置相关数据

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

时间:2024-12-31 10:57:19浏览次数:1  
标签:缓存 file configArr 存储配置 value char key PRINT LVGL

实现功能描述:

基于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

标签:缓存,file,configArr,存储配置,value,char,key,PRINT,LVGL
From: https://www.cnblogs.com/MrMoney/p/18643355

相关文章

  • mosdns 和 smartdns 都是常用的 DNS 代理工具,主要用于提高 DNS 查询的速度和效率,支持
    mosdns和smartdns都是常用的DNS代理工具,主要用于提高DNS查询的速度和效率,支持智能DNS查询、DNS缓存等功能。下面是这两个DNS工具的对比表格,帮助了解它们的区别和特点:功能/特性mosdnssmartdns主要功能提供快速的DNS查询服务,支持DNS缓存、加速等功能提......
  • nuxt 添加 redis 缓存
    这个文章的主要目的是通过redis缓存nuxt2中服务端渲染的页面。从而优化加载速度以及减轻服务端的压力。Nuxt是什么Nuxt.js是一个基于Vue.js的开源框架,旨在为开发者提供一个简单的方式来构建高性能的Vue应用。它提供了许多功能,使得开发服务器端渲染(SSR)、静态站点生成......
  • 本地更新正常但上传空间后无法更新缓存
    当您在本地环境中能够顺利地更新网站后台并保存更改,但在上传至虚拟主机后却遇到了无法更新缓存的问题时,这通常意味着存在某些配置差异或环境兼容性问题。以下是一些常见的原因及解决方案,帮助您更好地理解和处理这种情况:服务器环境差异:PHP版本不匹配:不同服务器可能运行着不同......
  • [4427] 13 缓存优化:那些基于缓存的优化方案
    上节课的思考题是Webpack4中TreeShaking的触发条件有哪些?我们一起来回忆一下,要让引入的模块支持TreeShaking,一般有4点需要注意:引入的模块需要是ES6类型的,CommonJS类型的则不支持。引入方式不能使用default。引用第三方依赖包的情况下,对应的package.json......
  • 【Spring】三级缓存解决循环依赖问题
    参考地址:Spring循环依赖:https://zhuanlan.zhihu.com/p/700890658Spring三级缓存解决循环依赖的问题:https://blog.csdn.net/Trong_/article/details/134063622  ==================================================================1.什么是循环依赖?1>说白是一个或多个对......
  • 146. LRU 缓存
    题目链接解题思路:用链表+哈希表。链表从头串到尾,淘汰时,从尾部开始淘汰。每次get时,如果找到了,则把这个节点移到头部。每次put,新建一个节点,放在头部,如果容量不够了,则淘汰尾部的数据。哈希表的作用是,能快速通过key找到链表中的节点。代码classLRUCache:classNode:......
  • redis缓存穿透和 缓存雪崩
    在使用Redis作为缓存系统时,缓存穿透(CachePenetration)和缓存雪崩(CacheAvalanche)是两种常见的问题。它们会影响缓存系统的性能和稳定性。以下是这两种问题的详细解释及其解决方法。缓存穿透(CachePenetration)缓存穿透是指查询一个在缓存和数据库中都不存在的数据,导致请求直接......
  • Redis缓存数据库
    1、介绍redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库redis的官网:redis.io注:域名后缀io属于国家域名,是britishIndianOceanterritory,即英属印度洋领地1、redis的特点:1.丰富的数据结构 -----string,list,set,zset,ha......
  • 大数据学习之Redis 缓存数据库二,Scala分布式语言一
    一.Redis缓存数据库二26.Redis数据安全_AOF持久化机制27.Redis数据安全_企业中该如何选择持久化机制28.Redis集群_主从复制概念29.Redis集群_主从复制搭建30.Redis集群_主从复制原理剖析31.Redis集群_哨兵监控概述32.Redis集群_配置哨兵监控33......
  • 如何做API抽象,一个在流水线上实现自缓存能力的例子
    通常每个流水线是独立执行的,每次执行的任务之间是无状态的,但是,每次任务都有输入和输出,输入是一个args是json,输出也是一个json,流水线执行环境提供了单次任务输入输出参数的持久化能力。利用这个特点,来实现一个有缓存状态的流水线执行API。首先,我们把调度平台的流水线的底层API先做......