Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
原创征文
SFDB简单文件型数据库
SFDB - 专为记录型数据存储而生
10.00
发布于 2023-08-15 17:11:04 浏览:2242
订阅该版
[tocm] # Simple and Fast ⚡ SFDB 即 Simple File Database, 一个 **简单** 的文件型数据库,使用 **简单**,移植 **简单**,功能 **简单**,原理 **简单**,一切都很 **简单**,一切都很 **快**。适用于 **固定长度** 的 **记录型** 数据存储,类似于时序数据库,可用于存储历史记录、报警记录、日志等。 如果你的项目需要记录数据,且数据的长度或最大长度是固定的,已存入的数据不需要修改,同时需要快速清空和基于 **记录条数** (从第几条开始,查多少条数据)的查询,而你的项目恰好有个文件系统,那么 SFDB 可能适合你。 **特性** - 使用文件进行存储 - 简单的数据写入接口 - 到达上限时自动从头覆盖 - 支持顺序与倒序查询 - 支持从任意条数开始查询 - 支持清空(重置)数据库 **最近完成了数据库文件分析工具的制作,可以直接对文件进行分析啦** 在线分析:[点我进入](http://sfdb.wkjay.com "点我进入") 源码仓库:[点我进入](https://github.com/WKJay/sfdb_web_ui "点我进入") ## 使用篇 本篇基于 HMI-Board 来演示 SFDB 的使用。 ### 创建工程 1. 使用 RT-Thread Studio 基于 HMI-Board 开发板创建一个项目。选项都保持默认即可。  2. 创建完成后打开 RT-Thread Settings,选中 `Enable SDCARD filesystem` 打开文件系统。  3. 在组件配置中打开 RTC 设备驱动,并使能 `使用软件模拟RTC设备选项`(提供给文件系统使用)。  4. 添加 SFDB 软件包。  1. 勾选 `SFDB` 配置项的 `Use sfdb example` 打开示例代码。  1. 全部配置完进行保存,当前软件包会就被应用到项目中。 ### 编译及下载 在编译之前,我们需要修改一下例程的配置,来适配我们的文件系统目录。打开 `packages/sfdb-v0.0.2/examples/rtthread/example.c`,找到宏定义 `TEST_FILE_PATH`,将其修改为 `/test.sdb`。  此处需要注意,sfdb 在不存在当前文件时会自动创建,但如果路径中包含有多层目录,则这些文件夹必须存在,即 sfdb 不会自动创建文件夹。 修改完路径配置后即可编译代码。  控制台看到上图的信息即编译成功,此时进行程序烧录。 ### 运行示例 程序下载完成后连接并打开终端,按下 `TAB` 键可以看到命令行中出现了两条 SFDB 的命令:  此时说明 SFDB 已经成功运行起来了。而这两条命令作用如下: - `sfdb_test`:启动 SFDB 写入测试,系统会持续写入到设定的上限值 - `sfdb_read`:读取测试数据库内的数据。 #### 写入测试 例程中设定的数据库存储上限为10000条,同时会写入10100条数据。接下来我们使用 `sfdb_test` 来启动写入测试:  可以看到日志中完整写入了10100条数据,而且每条数据的写入时间也都维持在 5-10 ms,并没有随着写入数量的增多而增大。 #### 读取测试 `sfdb_read`命令的形式有两种: - `sfdb_read` ***读取数据库基本信息*** - `sfdb_read [offset] [number] [order(0:asc 1:dsc)]` ***根据`order`从`offset`中读取`number`条数据*** ##### 1. 基本信息读取 基本信息不需要输入参数,直接 `sfdb_read` 即可:  可以看到,数据库的基本信息包括: 1. 当前最新数据的索引(容量10000,写入10100,多出来的将会从最老的数据开始覆盖) 2. 数据库中的总有效数据 3. 每条数据的长度 这些数据与我们的配置和写入也是完全一致的,说明我们刚才数据库的创建及写入操作是成功的。 ##### 2. 数据读取 读取的 `order` 为读取顺序,其中`0`为从最老的数据开始读,`1`为从最新的数据开始读: 1. 正序读取(从旧到新)  2. 倒序读取(从新到旧)  3. 注意 在倒序读取模式下,由于保留了读取性能, `buf` 的数据仍然是顺序的,使用者需要手动处理 `buf` 中的数据顺序。当数据 1-100 依次存入时,若以倒序从 offset 为 0 的位置读取 10 条数据,存入 buf 中,buf 中的数据顺序为 91 92 93 94 95 96 97 98 99 100 ,而非 100 99 98 97 96 95 94 93 92 91。使用者可以在应用层可以参考例程通过索引倒转的形式实现数据顺序的倒转,如下: ```c ret = sfdb_read(&sfdb, data_buf, data_sz, offset, number, order); for (int i = 0; i < ret; i++) { if (order == SFDB_READ_ASC) { print_index = i; } else { print_index = ret - i - 1; } SF_LOG("%-5d:%s", offset + i + 1, (char *)&data_buf[print_index * sfdb.hdr.record_len]); } ``` ## 移植篇 如果需要在别的平台使用SFDB,移植起来也是非常方便。仅需参考 `sfdb_port.c` 实现 `sfdb_fs_t` 里面的文件操作接口,以及在 `sfdb_port.h` 中包含当前平台所需要的头文件并实现 `SF_MEMCPY`、`SF_MEMSET`、`SF_LOG` 宏定义即可。 接口结构如下: ```c typedef struct _db_fs { int (*op)(struct _sfdb *db, const char *path, int flags); // Open file int (*cl)(void *fd); // Close file int (*sy)(void *fd); // Sync file size_t (*rd)(void *fd, void *buf, size_t len); // Read file size_t (*wr)(void *fd, const void *buf, size_t len); // Write file size_t (*sk)(void *fd, size_t offset); // Set file position int (*rm)(const char *path); // Delete file } sfdb_fs_t; ``` RT-Thread 下的移植示例: ```c // sfdb_port.c static int fs_open(sfdb_t *db, const char *path, int flags) { int oflags = O_RDWR; if (flags & SFDB_O_CREATE) oflags |= O_CREAT; db->fd = (void *)open(path, oflags); if ((int)db->fd < 0) { return -1; } else { return 0; } } static int fs_close(void *fd) { if (fd >= 0) { close((int)fd); return 0; } else { SF_LOG("invalid fd %d, close failed", (int)fd); return -1; } } static int fs_sync(void *fd) { return fsync((int)fd); } static size_t fs_read(void *fd, void *buf, size_t len) { return read((int)fd, buf, len); } static size_t fs_write(void *fd, const void *buf, size_t len) { return write((int)fd, buf, len); } static size_t fs_seek(void *fd, size_t offset) { int ret = 0; ret = lseek((int)fd, offset, SEEK_SET); if (ret < 0) return 0; return ret; } static int fs_remove(const char *path) { return unlink(path); } sfdb_fs_t sfdb_fs = { .op = fs_open, .cl = fs_close, .sy = fs_sync, .rd = fs_read, .wr = fs_write, .sk = fs_seek, .rm = fs_remove, }; ``` ```c // sfdb_port.h #include
#include
#include
#include
#include
#include
#define SF_MEMCPY rt_memcpy #define SF_MEMSET rt_memset #define SF_LOG(format, ...) rt_kprintf("[SFDB]:" format "\r\n", ##__VA_ARGS__) ``` ## 源码仓库 详细的API说明可以到源码的仓库查看: [Github](https://github.com/WKJay/sfdb) [Gitee](https://gitee.com/wangjunjie997/sfdb)
11
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
WKJay
wkjay.com
文章
10
回答
136
被采纳
24
关注TA
发私信
相关文章
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
编译报错
socket
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
11
个答案
3
次被采纳
xiaorui
3
个答案
3
次被采纳
踩姑娘的小蘑菇
6
个答案
2
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
11
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
9
次点赞
jinchanchan
2
篇文章
2
次点赞
alight
1
篇文章
5
次点赞
swet123
1
篇文章
4
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部