SQLite数据库如何存储和读取二进制数据
生活随笔
收集整理的這篇文章主要介紹了
SQLite数据库如何存储和读取二进制数据
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.?????? 存儲(chǔ)二進(jìn)制數(shù)據(jù)
?
?????? SQLite提供的綁定二進(jìn)制參數(shù)接口函數(shù)為:
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
?? 我們希望使用的是一套經(jīng)過封裝的COM接口,將上面這個(gè)函數(shù)封裝為COM接口的形式
BindParaByIndex( LONG index, VARIANT val);
?? 使用VARIANT變量來(lái)傳遞二進(jìn)制數(shù)據(jù),可以使用到它的一個(gè)SAFEARRAY指針,它保存了二進(jìn)制數(shù)據(jù)的地址和二進(jìn)制數(shù)據(jù)的字節(jié)長(zhǎng)度。
????? 在我們的COM接口中可以這樣進(jìn)行調(diào)用原始接口:
Sqlite3_bind_blob(m_pStmt, val.parray, val.parray->rsground->cElement,SQLITE_TRANSIENT);
? 構(gòu)造一個(gè)例子測(cè)試我們的接口:
??? BYTE Data[] = {0x01,0x02,0x03,0x04,0x05};
??? CComSafeArray<byte> *pcsfa;
??? CComSafeArrayBound bound[1];
??? bound[0].SetCount(5);
??? bound[0].SetLowerBound(0);
??? pcsfa = new CComSafeArray<byte>(bound,1);
??? for(LONG i = 0; i <(LONG)5; i++)
??? {
??????? HRESULT hr = pcsfa->SetAt(i,Data[i]);
??? }
??? _variant_t variant;
??? variant.vt = VT_ARRAY | VT_UI1;
??? variant.parray = pcsfa->m_psa;
?? 將五個(gè)字節(jié)的數(shù)據(jù)封裝到VARIANT變量中,然后調(diào)用相應(yīng)的接口,將它們存儲(chǔ)到數(shù)據(jù)庫(kù)中,然后
?? 調(diào)用下面的讀取二進(jìn)制接口,將數(shù)據(jù)讀取出來(lái),看是否讀取的數(shù)據(jù)和存儲(chǔ)的數(shù)據(jù)一致.
?
2.?????? 讀取二進(jìn)制數(shù)據(jù)
?
?? 讀取二進(jìn)制參數(shù)需要用到下面兩個(gè)SQLite提供的API:
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
??? 訪問也通過COM接口來(lái)實(shí)現(xiàn):
GetBlobData(LONG index, VARIANT* pval);
?? 如何將原始接口讀出來(lái)的數(shù)據(jù)封裝到VARIANT結(jié)構(gòu)中去呢,網(wǎng)上這方面的參考資料好少,差了不少資料,發(fā)現(xiàn)網(wǎng)上有不上SAFEARRAY的實(shí)現(xiàn)方案,但是我一一試了一下沒有一個(gè)可以將二進(jìn)制數(shù)讀入SAFEARRAY結(jié)構(gòu)的,Mentor給我推薦了一個(gè)CcomSafeArray類,這個(gè)類成功實(shí)現(xiàn)了數(shù)據(jù)的存儲(chǔ)。
CComVariant cVal;
int nLen = sqlite3_column_bytes(m_pStmt,nIndex);
const void* pcvData = (const void*)sqlite3_column_blob(m_pStmt,nIndex);
BYTE* pData = new BYTE[nLen];
memcpy(pData,pcvData,nLen);
CComSafeArray<byte> *pcsfa;
CComSafeArrayBound bound[1];
bound[0].SetCount(nLen);
bound[0].SetLowerBound(0);
pcsfa = new CComSafeArray<byte>(bound,1);
for(LONG i = 0; i <(LONG)nLen; i++)
{
HRESULT hr = pcsfa->SetAt(i,pData[i]);
}
cVal = pcsfa->m_psa;
cVal.vt = VT_ARRAY | VT_UI1;
delete pData;
cVal.Detach(pVal);
?? OK,現(xiàn)在可以通過下面的代碼來(lái)測(cè)試是否成功讀取了所有的二進(jìn)制數(shù)據(jù)。測(cè)試代碼如下:
_variant_t val;
val = GetBlobData(nIndex); //nIndex表示BLOB類型數(shù)據(jù)的索引值
byte buf[5];
if(val.vt == (VT_UI1|VT_ARRAY))
{
for(LONG index = 0; index < 5; index++)
{
??? ::SafeArrayGetElement(val.parray,&index,buf+index);
}
}
for(int j = 0; j < 5; j++)
{
cout << “0x” << hex <<(int) buf[j]<<endl;//測(cè)試結(jié)果為0x01,0x02,0x03,0x04,0x05
}
?
?????? SQLite提供的綁定二進(jìn)制參數(shù)接口函數(shù)為:
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
?? 我們希望使用的是一套經(jīng)過封裝的COM接口,將上面這個(gè)函數(shù)封裝為COM接口的形式
BindParaByIndex( LONG index, VARIANT val);
?? 使用VARIANT變量來(lái)傳遞二進(jìn)制數(shù)據(jù),可以使用到它的一個(gè)SAFEARRAY指針,它保存了二進(jìn)制數(shù)據(jù)的地址和二進(jìn)制數(shù)據(jù)的字節(jié)長(zhǎng)度。
????? 在我們的COM接口中可以這樣進(jìn)行調(diào)用原始接口:
Sqlite3_bind_blob(m_pStmt, val.parray, val.parray->rsground->cElement,SQLITE_TRANSIENT);
? 構(gòu)造一個(gè)例子測(cè)試我們的接口:
??? BYTE Data[] = {0x01,0x02,0x03,0x04,0x05};
??? CComSafeArray<byte> *pcsfa;
??? CComSafeArrayBound bound[1];
??? bound[0].SetCount(5);
??? bound[0].SetLowerBound(0);
??? pcsfa = new CComSafeArray<byte>(bound,1);
??? for(LONG i = 0; i <(LONG)5; i++)
??? {
??????? HRESULT hr = pcsfa->SetAt(i,Data[i]);
??? }
??? _variant_t variant;
??? variant.vt = VT_ARRAY | VT_UI1;
??? variant.parray = pcsfa->m_psa;
?? 將五個(gè)字節(jié)的數(shù)據(jù)封裝到VARIANT變量中,然后調(diào)用相應(yīng)的接口,將它們存儲(chǔ)到數(shù)據(jù)庫(kù)中,然后
?? 調(diào)用下面的讀取二進(jìn)制接口,將數(shù)據(jù)讀取出來(lái),看是否讀取的數(shù)據(jù)和存儲(chǔ)的數(shù)據(jù)一致.
?
2.?????? 讀取二進(jìn)制數(shù)據(jù)
?
?? 讀取二進(jìn)制參數(shù)需要用到下面兩個(gè)SQLite提供的API:
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
??? 訪問也通過COM接口來(lái)實(shí)現(xiàn):
GetBlobData(LONG index, VARIANT* pval);
?? 如何將原始接口讀出來(lái)的數(shù)據(jù)封裝到VARIANT結(jié)構(gòu)中去呢,網(wǎng)上這方面的參考資料好少,差了不少資料,發(fā)現(xiàn)網(wǎng)上有不上SAFEARRAY的實(shí)現(xiàn)方案,但是我一一試了一下沒有一個(gè)可以將二進(jìn)制數(shù)讀入SAFEARRAY結(jié)構(gòu)的,Mentor給我推薦了一個(gè)CcomSafeArray類,這個(gè)類成功實(shí)現(xiàn)了數(shù)據(jù)的存儲(chǔ)。
CComVariant cVal;
int nLen = sqlite3_column_bytes(m_pStmt,nIndex);
const void* pcvData = (const void*)sqlite3_column_blob(m_pStmt,nIndex);
BYTE* pData = new BYTE[nLen];
memcpy(pData,pcvData,nLen);
CComSafeArray<byte> *pcsfa;
CComSafeArrayBound bound[1];
bound[0].SetCount(nLen);
bound[0].SetLowerBound(0);
pcsfa = new CComSafeArray<byte>(bound,1);
for(LONG i = 0; i <(LONG)nLen; i++)
{
HRESULT hr = pcsfa->SetAt(i,pData[i]);
}
cVal = pcsfa->m_psa;
cVal.vt = VT_ARRAY | VT_UI1;
delete pData;
cVal.Detach(pVal);
?? OK,現(xiàn)在可以通過下面的代碼來(lái)測(cè)試是否成功讀取了所有的二進(jìn)制數(shù)據(jù)。測(cè)試代碼如下:
_variant_t val;
val = GetBlobData(nIndex); //nIndex表示BLOB類型數(shù)據(jù)的索引值
byte buf[5];
if(val.vt == (VT_UI1|VT_ARRAY))
{
for(LONG index = 0; index < 5; index++)
{
??? ::SafeArrayGetElement(val.parray,&index,buf+index);
}
}
for(int j = 0; j < 5; j++)
{
cout << “0x” << hex <<(int) buf[j]<<endl;//測(cè)試結(jié)果為0x01,0x02,0x03,0x04,0x05
}
轉(zhuǎn)載于:https://www.cnblogs.com/top5/archive/2009/11/26/1611479.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的SQLite数据库如何存储和读取二进制数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OOD之问题空间到解空间—附FP的建模
- 下一篇: 网易云音乐接口解析