使用ADO GetChunk/AppendChunk 数据库存取二进制文件图象
在设计数据库的过程中,我们会经常要存储一些图形、长文本、多媒体(视频、音频文件)等各种各样的程序文件,如果我们在数据库中仅存储这些文件的路径信息,尽管这可以大大地减小数据库的大小,但是由于文件存在磁盘上,我们除了维护数据库外还要维护文件的路径信息,保持二者的一致,这对于我们管理数据库非常不方便。我们还是寄希望能够把这些文件的内容作为一个记录的一个字段值存到数据库中,这样文件的上传和下载就变成了简单的字段读写。我们不用再考虑这些文件是如何在磁盘上存储的,数据库会帮我们做好一切工作。
SQL Server提供了多达2GB字节的字段类型(TEXT、IMAGE、NTEXT),这么大的空间可以说对于我们保存一般的文件已经足够了,我们可以把需要保存的虚拟光驱映象文件、MP3、AutoCAD图形、精美图片、RealPlayer视频音频文件等的内容存入到数据库中,根据用户检索的信息,再把对应的记录读出来,存到本地硬盘的一个临时文件中,然后用其对应的程序打开它,利用这种方法,我们可以实现在一个局域网中实现客户端的信息共享,也可以用这种方法做一个简单的视频点播系统,或者做一个WEB上传下载程序。但是由于这些文件的内容不是简单的文本信息,我们无法通过一般的粘贴和复制把它们写进去或者读出来,那么我们怎么才能读写这些二进制大字段(Binary Large Objects, BLOB)呢?
为了读写BLOB 字段,ADO为这些BLOB字段提供了两种方法GetChunk和AppendChunk,通过它们,你可以象读写文件一样,把其它文件的内容写进去读出来。
GetChunk方法
使用方法:variable = field.GetChunk( Size )
其中field为一个大文本或者二进制字段,size为要从该字段获得的字节或字符数。执行完将返回一个数据起始地址。由于系统限制,我们最好能够一部分一部分地从该字段获取数据,而不是整个把全部数据读出来。如果给定的size 大小大于该字段剩余没读出的的字节数,那么GetChunk仅返回剩余的数据;如果字段为空,将返回一个null值。
每一次顺序地调用GetChunk获取数据,都将从上一次读写没有读到的地方开始,然而如果你正从一个字段获取数据,然后又去设置或读取当前记录的另外一个字段,这样ADO就会认为你已经完成第一个字段的读取,如果你接着又读取第一个字段,ADO就会把这次调用视为一个新的GetChunk操作,将从数据的起始位置读写。如果你存取的是其它记录集对象,而且这个记录集不是第一个记录集的复制品,那么这个过程将不会打断GetChunk操作。
如果你想使用GetChunk方法读取一个字段,你必须把字段对象的Attributes属性的adFldLong位设置为真。如果你在一个没有当前记录的字段对象上使用GetChunk方法,将返回3021错误代码(没有当前记录)。
AppendChunk方法
使用方法:object.AppendChunk Dataobject 为一个字段或参数对象。
Data 为一个包含数据变量,这些数据将被追加到对象中。
同上面一样,如果你的系统内存有限,你尽可能分多次把数据追加到字段或参数对象。
如果你想使用AppendChunk 方法写一个字段,你需要把字段对象的字段Attributes属性的adFldLong位设置为真,第一次对一个字段对象使用AppendChunk方法,将会覆盖任何已有数据,后面调用AppendChunk将会把数据追加到存在数据的尾部。在向一个字段追加数据的时候,如果你又去设置或读取当前记录的另一个字段的值,ADO会认为你已经完成了对第一个字段的追加,再次对第一个字段调用AppendChunk方法,会被ADO解释为一次新的操作,从而覆盖已有数据。如果你存取的是其它记录集对象,而且这个记录集不是第一个记录集的复制品,那么这个过程将不会打断AppendChunk操作。如果你在一个没有当前记录的字段对象上使用AppendChunk方法,将返回错误信息(没有当前记录)。
下面是实现读写文件的过程例子,它已经被应用到一个学生管理系统,用于各个部门发布内部通知,通知的内容可以来自声音文件,视频文件,或者WORD文档,网页或电子表格、幻灯片等等,通知发布后,将作为一个记录存到数据库中,每个部门都可以下载到本地,进行察看浏览。这种方法可以广泛地应用到ASP中,开发上传或下载程序用。
1.把文件内容写到数据库中
Const BLOCKSIZE As Long = 4096
Sub FileToColumn(Col As ADODB.Field, DiskFile As String)
“从一个临时文件中获取数据,并把它保存到数据库中
“col为一个ADO字段,DiskFile为一个文件名,它可以为一个远程文件。
Dim strData() As Byte “声明一个动态数组
Dim NumBlocks As Long “读写块数
Dim FileLength As Long “文件长度
Dim LeftOver As Long “剩余字节数
Dim SourceFile As Long ‘文件句柄
Dim i As Long
SourceFile = FreeFile “获得剩余的文件句柄号
Open DiskFile For Binary Access Read As SourceFile “以二进制读方式打开源文件。
FileLength = LOF(SourceFile) “获得文件长度
If FileLength = 0 Then
Close SourceFile “关闭文件
Peedy.Speak DiskFile & " Empty or Not Found." ‘调用Msagent控件,提示信息
Else
NumBlocks = FileLength / BLOCKSIZE ‘获得块数
LeftOver = FileLength Mod BLOCKSIZE ‘最后一块的字节数
Col.AppendChunk Null ‘追加空值,清除已有数据
ReDim strData(BLOCKSIZE) ‘从文件中读取内容并写到文件中。
For i = 1 To NumBlocks
Get SourceFile, , strData
Col.AppendChunk strData
Next I
ReDim strData(LeftOver)
Get SourceFile, , strData
Col.AppendChunk strData
Close SourceFile
End If
End Sub
2.从数据库中把文件内容读出来,并写到一个文件中。
Private Sub ColumnToFile(Col As ADODB.Field, DiskFile As String, rsset As Recordset)
“从数据库获得数据并把它们写到硬盘上的一个临时文件中。
“快的大小以4096为单位
Dim NumBlocks As Long “注释见上文
Dim LeftOver As Long “
Dim strData() As Byte
Dim DestFileNum As Long
Dim i As Long
Dim ColSize As Long
“确保你存取的不是一个空记录集
If Not rsset.EOF And Not rsset.BOF Then
ColSize = Col.ActualSize
“获得列的实际大小
“如果文件长度为零,将删除文件内容
If Len(Dir$(DiskFile)) > 0 Then
Kill DiskFile
End If
DestFileNum = FreeFile
Open DiskFile For Binary As DestFileNum
NumBlocks = ColSize / BLOCKSIZE
LeftOver = ColSize Mod BLOCKSIZE
“把数据写到文件中
For i = 1 To NumBlocks
ReDim strData(BLOCKSIZE)
strData = Col.GetChunk(BLOCKSIZE)
Put DestFileNum, , strData
Next i
ReDim strData(LeftOver)
strData = Col.GetChunk(LeftOver)
Put DestFileNum, , strData
Close DestFileNum
End If
End Sub
3.具体使用
只要在SQL Server2000中创建数据表时,设置字段类型为Image即可,浏览本地文件需调用ShellExecute函数。
ShellExecute Me.hWnd,”Open”,szFileName, 0, 0, SW_SHOWNORMAL
本程序在Windows 2000环境下用Visual Basic 6和 SQL Server 2000 调试通过,采用的是Microsoft ADO Data Control 6.0控件。
http://blog.csdn.net/abcpanpeng/article/details/1650807
使用ADO GetChunk/AppendChunk 数据库存取二进制文件图象的更多相关文章
- 数据库存取缓冲区的LRU与MRU算法
数据库存取缓冲区的LRU与MRU算法 1.Cache Hit and Cache Miss 当使用者第一次向数据库发出查询数据的请求的时候,数据库会先在缓冲区中查找该数据,如果要访问的数据恰好已经在缓 ...
- .NET基础拾遗(6)ADO.NET与数据库开发基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...
- ADO访问Access数据库错误解决心得随笔
最近在用ADO访问Access数据库的时候出现了一个奇怪的错误,觉得有必要记录下来,和大家分享一下. 环境 win7 x86系统: VS2012编译器: Office2010: Access2000~ ...
- ado无法访问数据库问题
现象:以ADO方式访问数据库的C++程序,在一台计算机上能访问成功,在另一台计算机上却访问不成功,报告不能连接错误,并且这两台计算机都装有ado. 原因:ado版本不对 解决方案:下载KB983246 ...
- 浅析ado.net获取数据库元数据信息 DeriveParameters
写这个文章源于早先对ADO.Net获取数据库元数据上的认识,去年我在阅读ADO.Net Core Reference的时候曾经注意过DataSet的FillSchema的这个方法.这方面,在我之前的随 ...
- Android sqlite数据库存取图片信息
Android sqlite数据库存取图片信息 存储图片:bitmap private byte[] getIconData(Bitmap bitmap){ int size = bitmap.get ...
- .NET基础拾遗(8)ADO.NET与数据库开发基础
1.1 ADO.NET支持哪几种数据源? ① System.Data.SqlClient .NET程序员最常用的了.通过OLEDB或者ODBC都可以访问,但是SqlClient下的组件直接针对MSSQ ...
- MFC,ADO方式实现数据库操作
参考: MSDN数据访问编程 (MFC/ATL): https://msdn.microsoft.com/zh-cn/library/kd4ck1tt.aspx?f=255&MSPPError ...
- MySQL数据库--思维导图
MySQL数据库--思维导图
随机推荐
- JavaWeb 绝对路径与相对路径
JavaWeb 绝对路径与相对路径 CreateTime--2018年4月14日16:51:19 Author:Marydon 8.1 绝对路径 web项目不可能使用绝对路径,因为: 以文件的引用 ...
- Linux平台Boost的编译方法
本博客(http://blog.csdn.net/livelylittlefish)贴出作 者(三二一@小鱼)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Linux平台Boost的编译方法 Bo ...
- ORA-12519:数据的连接池访问过多
今天服务部同事问我一个问题,客户处的报表一半能打开,一半报错如下: Io 异常: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=185599744)(ERR ...
- sqlserver学习笔记(六)—— sqlserver内置函数(字符串、日期)
sqlserver中有很多内置函数,这里总结了一些常用的 一.关于字符串的函数: 1.CHARINDEX 寻找一个指定字符串在另一个字符串中的起始位置 SELECT CHARINDEX('world‘ ...
- EMQTT benchmark测试
#-c 最大的客户端数据, -i:时间间隔 -t:订阅主题 -q:订阅方式 ./emqtt_bench_sub -c 50000 -i 10 -t bench/%i -q 2 notice: You ...
- EMQ学习 ---集群
emqttd集群设置管理 一.先来看EMQ的文档定义:http://emqtt.com/docs/v1/cluster.html emqttd集群设置管理 假设部署两台服务器s1.emqtt.io, ...
- 摘:static,const,inline,define的意义
static 1) 产生背景 引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想 ...
- Python3 isidentifier() 方法
描述 Python3 isidentifier() 方法用于判断字符串是否是有效的 Python 标识符,可用来判断变量名是否合法. 语法 isidentifier() 方法语法: S.isident ...
- CentOS 之 Supervisor
CentOS 之 Supervisor supervisor是一个Linux上用来管理程序后台运行的工具,支持程序的自启动,挂掉重启,日志等功能.可配置程序随系统启动,并支持挂掉重启,增强程序稳定性. ...
- unity, AnimatorCullingMode的一个bug
我在一个fbx节点上添加了一个Animator,CullingMode设置为Cull Update Transforms(即如果没有激活的SkinnedRenderer就不更新骨骼动画),然后我将这个 ...