用vc实现对超长数据库字段的操作(2)转载
2010-03-10 08:55
246 查看
关 键 词:二进制 BLOB 数据库 VC
阅读提示:介绍了用VC实现对超长数据库字段操作方法的关键技术,并以Access2003环境下的数据库为例,在VC 6.0下进行了实现,给出了关键的程序代码。
维数被定义在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,ChunkSize);if(uIsRead==0) break;rgsabound[0].cElements =uIsRead; rgsabound[0].lLbound = 0;psa = SafeArrayCreate(VT_UI1,1,rgsabound); ///创建SAFEARRAY对象for(long index=0;index<uIsRead;index++) SafeArrayPutElement(psa,&index,&bVal[index]);varChunk.vt = VT_ARRAY|VT_UI1;varChunk.parray = psa;//加入BLOB类型的数据m_pRecordset->Fields->GetItem("data")->AppendChunk(varChunk); ::VariantClear(&varChunk);::SafeArrayDestroyData( psa);if(uIsRead<ChunkSize) break;}
我们所有的读入数据工作都在一个while循环中实现,每次读入一个数据包,直到读完这个数据,即数据量为二进制数据的长度ChunkSize。其中*pBuf为指向缓冲区指针,即要读入的数据包。ChunkSize为VARIANT变量,用于保存二进制数据,psa是指向安全数组SAFEARRAY的指针。
3.3 从数据库读出二进制对象到文件
同样,由于这个二进制对象可能很大,无法将所有内容一次性读入内存中对应于保存数据时我们所使用的AppendChunk函数,读取数据应该使用GetChunk函数,GetChunk的原型如下:
_variant_t GetChunk (long Length );唯一的参数Length代表需要读取的字节数。
实现的关键代码如下:
long lBlobSize = m_pRecordset->Fields-> Item["data"] ->ActualSize; while(lBlobSize>0){lIsRead= lBlobSize >=ChunkSize? ChunkSize: lBlobSize;//从字段data中获取一个数据包varChunk = m_pRecordset->Fields->Item["data"]->GetChunk(lIsRead);for(index=0;index<lIsRead;index++) ::SafeArrayGetElement(varChunk.parray,&index,buf+index); //将数据包写入文件f.Write(buf,lIsRead);lBlobSize -=lIsRead;}
其中f是一个CFile对象,代表了要存储的文件。Long型变量lBlobSize记录了二进制对象的大小。利用一个while循环,每次从数据库中读取lIsRead字节,直至将其全部读出。
4 结束语
由于信息技术的飞速发展,特别是多媒体技术的广泛运用,可以预见,以后数据库中大对象的应用将日益普遍,有关大对象的存取势必将是数据库技术的一个发展方向。本文讨论了二进制大对象BLOB在数据库中的存储与读取的VC实现,能够满足基本的系统要求,具备了一定的可移植性,为今后更广泛的应用和更深入的研究提供的借鉴基础。
阅读提示:介绍了用VC实现对超长数据库字段操作方法的关键技术,并以Access2003环境下的数据库为例,在VC 6.0下进行了实现,给出了关键的程序代码。
维数被定义在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,ChunkSize);if(uIsRead==0) break;rgsabound[0].cElements =uIsRead; rgsabound[0].lLbound = 0;psa = SafeArrayCreate(VT_UI1,1,rgsabound); ///创建SAFEARRAY对象for(long index=0;index<uIsRead;index++) SafeArrayPutElement(psa,&index,&bVal[index]);varChunk.vt = VT_ARRAY|VT_UI1;varChunk.parray = psa;//加入BLOB类型的数据m_pRecordset->Fields->GetItem("data")->AppendChunk(varChunk); ::VariantClear(&varChunk);::SafeArrayDestroyData( psa);if(uIsRead<ChunkSize) break;}
我们所有的读入数据工作都在一个while循环中实现,每次读入一个数据包,直到读完这个数据,即数据量为二进制数据的长度ChunkSize。其中*pBuf为指向缓冲区指针,即要读入的数据包。ChunkSize为VARIANT变量,用于保存二进制数据,psa是指向安全数组SAFEARRAY的指针。
3.3 从数据库读出二进制对象到文件
同样,由于这个二进制对象可能很大,无法将所有内容一次性读入内存中对应于保存数据时我们所使用的AppendChunk函数,读取数据应该使用GetChunk函数,GetChunk的原型如下:
_variant_t GetChunk (long Length );唯一的参数Length代表需要读取的字节数。
实现的关键代码如下:
long lBlobSize = m_pRecordset->Fields-> Item["data"] ->ActualSize; while(lBlobSize>0){lIsRead= lBlobSize >=ChunkSize? ChunkSize: lBlobSize;//从字段data中获取一个数据包varChunk = m_pRecordset->Fields->Item["data"]->GetChunk(lIsRead);for(index=0;index<lIsRead;index++) ::SafeArrayGetElement(varChunk.parray,&index,buf+index); //将数据包写入文件f.Write(buf,lIsRead);lBlobSize -=lIsRead;}
其中f是一个CFile对象,代表了要存储的文件。Long型变量lBlobSize记录了二进制对象的大小。利用一个while循环,每次从数据库中读取lIsRead字节,直至将其全部读出。
4 结束语
由于信息技术的飞速发展,特别是多媒体技术的广泛运用,可以预见,以后数据库中大对象的应用将日益普遍,有关大对象的存取势必将是数据库技术的一个发展方向。本文讨论了二进制大对象BLOB在数据库中的存储与读取的VC实现,能够满足基本的系统要求,具备了一定的可移植性,为今后更广泛的应用和更深入的研究提供的借鉴基础。
相关文章推荐
- 用VC实现对超长数据库字段的操作
- 用SQLDMO实现对数据库备份还原操作 (转载)
- VC实现ODBC数据库操作实例解析
- 树的操作(绑定数据库,添加新节点,删除节点)(转载加实现)
- VC++实现数据库操作和应用程序操作的分离
- vc实现图片的数据库储存(转载)
- vc++实现对列表框的操作 ado 操作数据库实现对数据的增删 access
- VC++中ADO方式操作数据库之有关“datetime”字段的操作
- 在JAVA下实现数据库对word文件的读取与字段的提取
- jQuery EasyUI+ashx实现数据库的CIUD操作
- VC++下使用ADO编写数据库程序 – 操作大全
- 基于VC的网页元素操作实现技术
- 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等
- jquery+ajax+C#实现无刷新操作数据库数据的简单实例
- 使用JdbcTemplate简化JDBC操作 实现数据库操作
- 使用Spring JdbcTemplate实现数据库操作
- [转载] 为 Key-Value 数据库实现 MVCC 事务
- 使用XML封装数据库操作语句的实现
- (转载)Android数据库高手秘籍(六)——LitePal的修改和删除操作
- 用FineReport报表工具实现字段拼接回填数据库