SQLite数据库如何存储和读取二进制数据
1. 存储二进制数据
SQLite提供的绑定二进制参数接口函数为: int sqlite3_bind_blob(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); 我们希望使用的是一套经过封装的COM接口,将上面这个函数封装为COM接口的形式 BindParaByIndex( LONG index,VARIANT val); 使用VARIANT变量来传递二进制数据,可以使用到它的一个SAFEARRAY指针,它保存了二进制数据的地址和二进制数据的字节长度。 在我们的COM接口中可以这样进行调用原始接口: Sqlite3_bind_blob(m_pStmt,val.parray,val.parray->rsground->cElement,SQLITE_TRANSIENT); 构造一个例子测试我们的接口: 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; 将五个字节的数据封装到VARIANT变量中,然后调用相应的接口,将它们存储到数据库中,然后 调用下面的读取二进制接口,将数据读取出来,看是否读取的数据和存储的数据一致.
2. 读取二进制数据
读取二进制参数需要用到下面两个SQLite提供的API: const void *sqlite3_column_blob(sqlite3_stmt*,int iCol); int sqlite3_column_bytes(sqlite3_stmt*,int iCol);
访问也通过COM接口来实现: GetBlobData(LONG index,VARIANT* pval); 如何将原始接口读出来的数据封装到VARIANT结构中去呢,网上这方面的参考资料好少,差了不少资料,发现网上有不上SAFEARRAY的实现方案,但是我一一试了一下没有一个可以将二进制数读入SAFEARRAY结构的,Mentor给我推荐了一个CcomSafeArray类,这个类成功实现了数据的存储。 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,现在可以通过下面的代码来测试是否成功读取了所有的二进制数据。测试代码如下: _variant_t val; val = GetBlobData(nIndex); //nIndex表示BLOB类型数据的索引值 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;//测试结果为0x01,0x05 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |