Simple and Fast
SFDB 即 Simple File Database, 一個 簡單 的文件型數據庫,使用 簡單,移植 簡單,功能 簡單,原理 簡單,一切都很 簡單,一切都很 快。適用于 固定長度 的 記錄型 數據存儲,類似于時序數據庫,可用于存儲歷史記錄、報警記錄、日志等。
如果你的項目需要記錄數據,且數據的長度或最大長度是固定的,已存入的數據不需要修改,同時需要快速清空和基于 記錄條數 (從第幾條開始,查多少條數據)的查詢,而你的項目恰好有個文件系統,那么 SFDB 可能適合你。
特性
-
使用文件進行存儲
-
簡單的數據寫入接口
-
到達上限時自動從頭覆蓋
-
支持順序與倒序查詢
-
支持從任意條數開始查詢
-
支持清空(重置)數據庫
使用篇
本篇基于 HMI-Board 來演示 SFDB 的使用。
創建工程
1. 使用 RT-Thread Studio 基于 HMI-Board 開發板創建一個項目。選項都保持默認即可。
2. 創建完成后打開 RT-Thread Settings,選中 Enable SDCARD filesystem 打開文件系統。
3. 在組件配置中打開 RTC 設備驅動,并使能 使用軟件模擬RTC設備選項(提供給文件系統使用)。
4.添加 SFDB 軟件包。
5. 勾選 SFDB 配置項的 Use sfdb example 打開示例代碼。
6. 全部配置完進行保存,當前軟件包會就被應用到項目中。
編譯及下載
在編譯之前,我們需要修改一下例程的配置,來適配我們的文件系統目錄。打開 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 即可:
可以看到,數據庫的基本信息包括:
這些數據與我們的配置和寫入也是完全一致的,說明我們剛才數據庫的創建及寫入操作是成功的。
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。使用者可以在應用層可以參考例程通過索引倒轉的形式實現數據順序的倒轉,如下:
1ret=sfdb_read(&sfdb,data_buf,data_sz,offset,number,order); 2for(inti=0;i3if(order==SFDB_READ_ASC){ 4print_index=i; 5}else{ 6print_index=ret-i-1; 7} 8SF_LOG("%-5d:%s",offset+i+1,(char*)&data_buf[print_index*sfdb.hdr.record_len]); 9}
移植篇
如果需要在別的平臺使用SFDB,移植起來也是非常方便。僅需參考 sfdb_port.c 實現 sfdb_fs_t 里面的文件操作接口,以及在 sfdb_port.h 中包含當前平臺所需要的頭文件并實現 SF_MEMCPY、SF_MEMSET、SF_LOG 宏定義即可。
接口結構如下:
1typedefstruct_db_fs{ 2int(*op)(struct_sfdb*db,constchar*path,intflags);//Openfile 3int(*cl)(void*fd);//Closefile 4int(*sy)(void*fd);//Syncfile 5size_t(*rd)(void*fd,void*buf,size_tlen);//Readfile 6size_t(*wr)(void*fd,constvoid*buf,size_tlen);//Writefile 7size_t(*sk)(void*fd,size_toffset);//Setfileposition 8int(*rm)(constchar*path);//Deletefile 9}sfdb_fs_t;
RT-Thread 下的移植示例:
1//sfdb_port.c 2staticintfs_open(sfdb_t*db,constchar*path,intflags){ 3intoflags=O_RDWR; 4if(flags&SFDB_O_CREATE)oflags|=O_CREAT; 5db->fd=(void*)open(path,oflags); 6if((int)db->fd0){ 7return-1; 8}else{ 9return0; 10} 11} 12staticintfs_close(void*fd){ 13if(fd>=0){ 14close((int)fd); 15return0; 16}else{ 17SF_LOG("invalidfd%d,closefailed",(int)fd); 18return-1; 19} 20} 21staticintfs_sync(void*fd){returnfsync((int)fd);} 22staticsize_tfs_read(void*fd,void*buf,size_tlen){returnread((int)fd,buf,len);} 23staticsize_tfs_write(void*fd,constvoid*buf,size_tlen){returnwrite((int)fd,buf,len);} 24staticsize_tfs_seek(void*fd,size_toffset){ 25intret=0; 26ret=lseek((int)fd,offset,SEEK_SET); 27if(ret0)return0; 28returnret; 29} 30staticintfs_remove(constchar*path){returnunlink(path);} 31sfdb_fs_tsfdb_fs={ 32.op=fs_open, 33.cl=fs_close, 34.sy=fs_sync, 35.rd=fs_read, 36.wr=fs_write, 37.sk=fs_seek, 38.rm=fs_remove, 39};
1//sfdb_port.h 2#include
源碼倉庫
詳細的API說明可以到源碼的倉庫查看:
Github:https://github.com/WKJay/sfdb
Gitee:https://gitee.com/wangjunjie997
———————End———————
點擊閱讀原文進入官網
-
RT-Thread
+關注
關注
31文章
1291瀏覽量
40167
原文標題:SFDB - 專為記錄型數據存儲而生
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論