- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
如何用VC实现对超长数据库字段操作1前言数据库在实际的开发过程中.doc
如何用VC实现对超长数据库字段操作
1 前言
数据库在实际的开发过程中常常需要存储较大的二进制数据对象,如图像、音频文件、视频文件或其他二进制数据,这些数据称之为二进制大对象BLOB(Binary Large Object),其存取方式与普通数据有所区别。在数据库的表中,BLOB实际上是以二进制数据的形式存放的。由于BLOB的特殊性,一般的程序都无法处理它。比如,如果在一张表中存在BLOB,当用access或Database DeskTop(Delphi在带的数据库管理工具)等打开它时,BLOB列将只显示BLOB字样。至于该列中实际存的是什么数据单靠access(Database DeskTop)是无法得到的。如果在我们编制的程序中,用控件打开一个有BLOB字段的表,效果也一样。我们的程序无法直接显示、编辑以及插入BLOB字段。可见,如何处理这种不能直接显示的二进制形式数据,用常规的方法是不能满足要求的。
结合笔者开发的模型库管理系统,本文以Visual C++ 6.0和access 2003环境下的数据库为例,介绍利用ADO实现对超长数据库字段的访问,包括写入和读出。
2 设计数据库
使用Access2003作为数据库系统,数据库名为blob,唯一的一个数据表为blob,如下所示。
其中包括四个字段,分别是id(文本),name(文本),data(OLE对象)和suffix(后缀名),其字段类型必须是OLE对象。id作为主键,name是该blob文件的文件名,data字段用来保存二进制大对象,suffix是二进制文件的后缀名,可以是rm,avi,bmp,mp3等。
3 系统的实现
3.1 SafeArray:
在对BLOB进行操作时,要用到SAFEARRAY结构。SAFEARRAY是一种结构化的数据类型,包含了一个由其它数据类型的数据元素组成的数组。之所以称之为安全的数组是因为它包含了每一维的边界信息,并限制在边界内进行数组元素的访问。其Win32定义SAFEARRAY如下:
typedef struct tagSAFEARRAY
{
unsigned short cDims;
unsigned short fFeatures;
unsigned long cbElements;
unsigned long cLocks;
void * pvData;
SAFEARRAYBOUND rgsabound[ 1 ];
} SAFEARRAY; 这个结构的成员(cDims,cLocks等)是通过API函数来设置和管理的。真正的数据存放在pvData成员中,而SAFEARRAYBOUND结构定义该数组结构的细节。以下就是该结构成员的简要描述:
rgsabound是一个有趣的成员,它的结构不太直观。它是数据范围的数组。该数组的大小依safe array维数的不同而有所区别。rgsabound成员是一个SAFEARRAYBOUND结构的数组--每个元素代表SAFEARRAY的一个维。
typedef struct tagSAFEARRAYBOUND
{
unsigned long cElements;
unsigned long lLbound;
} SAFEARRAYBOUND; 维数被定义在cDims成员中。例如,一个C类数组的维数可以是[3][4][5]-一个三维的数组。如果我们使用一个SAFEARRAY来表示这个结构,我们定义一个有三个元素的rgsabound数组--一个代表一维。cDims = 3; SAFEARRAYBOUND rgsabound[ 3 ]; rgsabound[0]元素定义第一维。在这个例子中ILBOUND元素为0,是数组的下界。cElements成员的值等于三。数组的第二维([4])可以被rgsabound结构的第二个元素定义。下界也可以是0,元素的个数是4,第三维也是这样。
3.2 将二进制文件写入到数据库:
由于这个二进制文件可能很大,所以无法将所有内容一次性读入到内存。我们需要多次读入,每次可以使用函数CFile::Read()从文件中读出一个数据包,然后调用Field对象的AppandChrnk()函数将该包读入数据库。AppandChrnk()函数包含在Field对象中,原型如下:HRESULT AppendChunk (const _variant_t Data );从函数原型中可以看到关键的问题是我们需把二进制数据赋值给VARIANT类型的变量。实现的关键代码如下:
while(1)
{ uIsRead=f.Read(bVal,
您可能关注的文档
最近下载
- 2024电梯监督检验和定期检验指南第1部分:乘客和载货电梯.pdf VIP
- 合成药物工艺研究.pptx VIP
- 电气预防性试验及防雷试验工程方案投标文件(技术方案).doc
- 基于“六位一体”内部控制的创新实践.pdf VIP
- 外商投资产业指导目录(2007年修订)(全文).doc VIP
- 新一代大学英语(提高篇)视听说教程 1 B1U1.pptx VIP
- 2025年秋新人教版数学三年级上册全册课件.pptx
- 吉J2020-011:木塑复合材料景观工程构造.pdf VIP
- 2024电梯监督检验和定期检验指南第3部分:杂物电梯.docx VIP
- 服装裁剪与制作(第三版)全书电子教案教学课件汇总.ppt
文档评论(0)