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, 数据库
posted @ 2013-08-11 18:00 ZWmaqing 阅读(...) 评论(...) 编辑 收藏

var allowComments=true,cb_blogId=152274,cb_entryId=3251712,cb_blogApp=currentBlogApp,cb_blogUserGuid='59ae949f-d5c2-e211-8d02-90b11c0b17d6',cb_entryCreatedDate='2013/8/11 18:00:00';loadViewCount(cb_entryId);

SQLite数据库如何存储和读取二进制数据的更多相关文章

  1. JDBC存储和读取二进制数据

    以下JSP文件用common-fileupload组件实现文件上传,并将文件以二进制文件的形式存入数据库 <% if("POST".equalsIgnoreCase(requ ...

  2. [19/05/07-星期二] JDBC(Java DataBase Connectivity)_CLOB(存储大量的文本数据)与BLOB(存储大量的二进制数据)

    一. CLOB(Character Large Object ) – 用于存储大量的文本数据 – 大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式来处理的.而非一般的字段,一次 ...

  3. (第二章第三部分)TensorFlow框架之读取二进制数据

    系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html (第二章第二部分)Tens ...

  4. C# 在SQLite数据库中存储图像 z

    C# 在SQLite数据库中存储图像 更多 0 C# SQLite   建表语句 CREATE TABLE [ImageStore]([ImageStore_Id] INTEGER NOT NULL ...

  5. python 读取二进制数据到可变缓冲区中

    想直接读取二进制数据到一个可变缓冲区中,而不需要做任何的中间复制操作.或者你想原地修改数据并将它写回到一个文件中去. 为了读取数据到一个可变数组中,使用文件对象的readinto() 方法.比如 im ...

  6. SharedPreferences数据、openFileOutput文件、SQLite数据库文件存储位置

    在模拟器中: SharedPreferences将XML文件保存在/data/data/<package name>/shared_prefs目录下, openFileOutput方法将文 ...

  7. sqlite数据库 select 查询带换行符数据

    在sqlite 数据库中用 select 语句查询带 换行符的 数据信息 实现 SELECT   * from questions_exec where title like     '%'||x'0 ...

  8. BLOB存储图片文件二进制数据是非对错

    子在一天一天虚度,生活也在一天一天中茫然 做人做事哪能尽如人意,付出多少收获多少虽然存在偏颇,但是不劳而获的心态是万万不对的,更不能去怨天尤人,低调为人.做好自己就可以了 改进你的系统的最好的方法是先 ...

  9. SQLite入门(二)读写二进制数据

    //读二进制数据的函数 BOOL OpenBinDataFile(BYTE **pBUf,UINT &len) {     if (pBUf == NULL)     {         re ...

随机推荐

  1. csuoj 1355: 地雷清除计划

    这是一个非常神奇的题: 感觉像一个模拟搜索: 但是竟然可以用网络流来解决: 直接粘题解把: 如果不能走通的话,必然说明能够从右上角(图外面)沿雷“跳” ,一直可以“跳”左下角(图外面) ,因此建好图之 ...

  2. JniHelper 含安卓推送

    using System; using System.Runtime.CompilerServices; using UnityEngine; internal static class JniHel ...

  3. Android 自定义seekbar中,thumb被覆盖掉一部分问题

    (图一)  (图二)    (图三) 做一个自定义的seekbar,更改其背景图片: <com.android.Progress android:id="@+id/focus_seek ...

  4. IDM和ODM

    DM (Integrated Data Multiplexer):综合数据复用器[1]  综合数据复用器是一种数据复用设备,它可以将多路RS232.RS485及数字语音等多种数据复用到E1传输通道或光 ...

  5. 【原创】MIPS·Verilog·FPGA

    时至今日,终于将全部的计划55条MIPS指令在FPGA上全部验证完毕,通过这近一个月的不断的修改调试.修改调试,我对整个流程对MIPS有了深刻的体会和认识.借着刚刚现阶段任务的兴奋和短暂的空闲时间,将 ...

  6. 如何配置Java环境

    下载JDK并安装 搜索JDK,官网立马就出来了,下载之后个人觉得毕竟开发,毕竟这东西不大,C盘稳一点,安装在C盘可以的 配置 右键打开计算机->属性->高级系统设置->高级-> ...

  7. 深入浅MFC

    视图类CView 在MFC"文档/视图"架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口.在"文档/视图"架构中,文档负责管理和维护数 ...

  8. [LOJ 1008] Fibsieve`s Fantabulous Birthday

    A - Fibsieve`s Fantabulous Birthday Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%l ...

  9. 从零开始学习jQuery (七) jQuery动画-让页面动起来!

    一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 开发人员一直痛疼做动画. 但是有了jQuery你 ...

  10. [转]NHibernate之旅(13):初探立即加载机制

    本节内容 引入 立即加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过上一篇的介绍,我们知道了NHibernate中默认的加载机制——延迟加载.其本质就是使用GoF23中代理模式 ...