zoukankan      html  css  js  c++  java
  • SQLite数据库如何存储和读取二进制数据

    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,0x02,0x03,0x04,0x05

    }
    分类: Sqlite, 数据库
  • 相关阅读:
    曾经写的一些文章,与技术无关,整理出来怀旧,:)
    在VS.NET2003中使用XHTML的插件HTML TIDY 及 MindManger
    把机器退出了域,造成无法启动 MSSQLSERVER ,晕
    hello php!
    今天又看了一下存储过程
    [转]PAGEII携手极速网爱情电影经典对白
    关键词:2005年,世乒赛.上海,乒乓的胜地
    一本SharePoint方面的书,Special Edition Using Microsoft® SharePoint Portal Server
    keo计划
    关于xp_cmdshell 。。注意安全!
  • 原文地址:https://www.cnblogs.com/sczw-maqing/p/3251712.html
Copyright © 2011-2022 走看看