实现功能描述:
基于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