Simple and Fast
SFDB 即 Simple File Database, 一個(gè) 簡(jiǎn)單 的文件型數(shù)據(jù)庫(kù),使用 簡(jiǎn)單,移植 簡(jiǎn)單,功能 簡(jiǎn)單,原理 簡(jiǎn)單,一切都很 簡(jiǎn)單,一切都很 快。適用于 固定長(zhǎng)度 的 記錄型 數(shù)據(jù)存儲(chǔ),類似于時(shí)序數(shù)據(jù)庫(kù),可用于存儲(chǔ)歷史記錄、報(bào)警記錄、日志等。
如果你的項(xiàng)目需要記錄數(shù)據(jù),且數(shù)據(jù)的長(zhǎng)度或最大長(zhǎng)度是固定的,已存入的數(shù)據(jù)不需要修改,同時(shí)需要快速清空和基于 記錄條數(shù) (從第幾條開始,查多少條數(shù)據(jù))的查詢,而你的項(xiàng)目恰好有個(gè)文件系統(tǒng),那么 SFDB 可能適合你。
特性
-
使用文件進(jìn)行存儲(chǔ)
-
簡(jiǎn)單的數(shù)據(jù)寫入接口
-
到達(dá)上限時(shí)自動(dòng)從頭覆蓋
-
支持順序與倒序查詢
-
支持從任意條數(shù)開始查詢
-
支持清空(重置)數(shù)據(jù)庫(kù)
使用篇
本篇基于 HMI-Board 來(lái)演示 SFDB 的使用。
創(chuàng)建工程
1. 使用 RT-Thread Studio 基于 HMI-Board 開發(fā)板創(chuàng)建一個(gè)項(xiàng)目。選項(xiàng)都保持默認(rèn)即可。
2. 創(chuàng)建完成后打開 RT-Thread Settings,選中 Enable SDCARD filesystem 打開文件系統(tǒng)。
3. 在組件配置中打開 RTC 設(shè)備驅(qū)動(dòng),并使能 使用軟件模擬RTC設(shè)備選項(xiàng)(提供給文件系統(tǒng)使用)。
4.添加 SFDB 軟件包。
5. 勾選 SFDB 配置項(xiàng)的 Use sfdb example 打開示例代碼。
6. 全部配置完進(jìn)行保存,當(dāng)前軟件包會(huì)就被應(yīng)用到項(xiàng)目中。
編譯及下載
在編譯之前,我們需要修改一下例程的配置,來(lái)適配我們的文件系統(tǒng)目錄。打開 packages/sfdb-v0.0.2/examples/rtthread/example.c,找到宏定義 TEST_FILE_PATH,將其修改為 /test.sdb。
此處需要注意,sfdb 在不存在當(dāng)前文件時(shí)會(huì)自動(dòng)創(chuàng)建,但如果路徑中包含有多層目錄,則這些文件夾必須存在,即 sfdb 不會(huì)自動(dòng)創(chuàng)建文件夾。
修改完路徑配置后即可編譯代碼。
控制臺(tái)看到上圖的信息即編譯成功,此時(shí)進(jìn)行程序燒錄。
運(yùn)行示例
程序下載完成后連接并打開終端,按下 TAB 鍵可以看到命令行中出現(xiàn)了兩條 SFDB 的命令:
此時(shí)說明 SFDB 已經(jīng)成功運(yùn)行起來(lái)了。而這兩條命令作用如下:
-
sfdb_test:?jiǎn)?dòng) SFDB 寫入測(cè)試,系統(tǒng)會(huì)持續(xù)寫入到設(shè)定的上限值
-
sfdb_read:讀取測(cè)試數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)。
寫入測(cè)試
例程中設(shè)定的數(shù)據(jù)庫(kù)存儲(chǔ)上限為10000條,同時(shí)會(huì)寫入10100條數(shù)據(jù)。接下來(lái)我們使用 sfdb_test 來(lái)啟動(dòng)寫入測(cè)試:
可以看到日志中完整寫入了10100條數(shù)據(jù),而且每條數(shù)據(jù)的寫入時(shí)間也都維持在 5-10 ms,并沒有隨著寫入數(shù)量的增多而增大。
讀取測(cè)試
sfdb_read命令的形式有兩種:
-
sfdb_read 讀取數(shù)據(jù)庫(kù)基本信息
-
sfdb_read [offset] [number] [order(0:asc 1:dsc)] 根據(jù)order從offset中讀取number條數(shù)據(jù)
1. 基本信息讀取
基本信息不需要輸入參數(shù),直接 sfdb_read 即可:
可以看到,數(shù)據(jù)庫(kù)的基本信息包括:
-
當(dāng)前最新數(shù)據(jù)的索引(容量10000,寫入10100,多出來(lái)的將會(huì)從最老的數(shù)據(jù)開始覆蓋)
-
數(shù)據(jù)庫(kù)中的總有效數(shù)據(jù)
-
每條數(shù)據(jù)的長(zhǎng)度
這些數(shù)據(jù)與我們的配置和寫入也是完全一致的,說明我們剛才數(shù)據(jù)庫(kù)的創(chuàng)建及寫入操作是成功的。
2. 數(shù)據(jù)讀取
讀取的 order 為讀取順序,其中0為從最老的數(shù)據(jù)開始讀,1為從最新的數(shù)據(jù)開始讀:
- 1. 正序讀?。◤呐f到新)
- 2.倒序讀?。◤男碌脚f)
- 3. 注意
在倒序讀取模式下,由于保留了讀取性能, buf 的數(shù)據(jù)仍然是順序的,使用者需要手動(dòng)處理 buf 中的數(shù)據(jù)順序。當(dāng)數(shù)據(jù) 1-100 依次存入時(shí),若以倒序從 offset 為 0 的位置讀取 10 條數(shù)據(jù),存入 buf 中,buf 中的數(shù)據(jù)順序?yàn)?91 92 93 94 95 96 97 98 99 100 ,而非 100 99 98 97 96 95 94 93 92 91。使用者可以在應(yīng)用層可以參考例程通過索引倒轉(zhuǎn)的形式實(shí)現(xiàn)數(shù)據(jù)順序的倒轉(zhuǎn),如下:
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}
移植篇
如果需要在別的平臺(tái)使用SFDB,移植起來(lái)也是非常方便。僅需參考 sfdb_port.c 實(shí)現(xiàn) sfdb_fs_t 里面的文件操作接口,以及在 sfdb_port.h 中包含當(dāng)前平臺(tái)所需要的頭文件并實(shí)現(xiàn) SF_MEMCPY、SF_MEMSET、SF_LOG 宏定義即可。
接口結(jié)構(gòu)如下:
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
源碼倉(cāng)庫(kù)
詳細(xì)的API說明可以到源碼的倉(cāng)庫(kù)查看:
Github:https://github.com/WKJay/sfdb
Gitee:https://gitee.com/wangjunjie997
———————End———————
點(diǎn)擊閱讀原文進(jìn)入官網(wǎng)
原文標(biāo)題:SFDB - 專為記錄型數(shù)據(jù)存儲(chǔ)而生
文章出處:【微信公眾號(hào):RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
RT-Thread
+關(guān)注
關(guān)注
31文章
1289瀏覽量
40135
原文標(biāo)題:SFDB - 專為記錄型數(shù)據(jù)存儲(chǔ)而生
文章出處:【微信號(hào):RTThread,微信公眾號(hào):RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論