使用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数据库--思维导图
随机推荐
- 转:发一个自己用过的makefile .
#gcc test.cpp -L. -Wl,-Bdynamic -ltestlib -Wl,-Bstatic -ltestlib -Wl,-Bdynamic #make clean; make in ...
- spring mvc 返回json的配置
转载自:http://my.oschina.net/haopeng/blog/324934 springMVC-servlet.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- 【jquery操作cookie】JQuery中$.cookie()方法的使用(同名cookie会覆盖)
jquery.cookie.js插件: <script type="text/javascript" src="js/jquery-1.6.2.min.js&quo ...
- 使用vs调试.net源代码
使用.NET Framework库参考源进行调试 您可能会想知道使用.NET Framework参考源的调试方式.在下面的示例中,您将看到一个我调用公用Console.WriteLine方法的工具.从 ...
- freeswitch编译java esl
一.背景假设源代码路径为/home/freeswitch 二.编译安装libesl.a1. cd /home/freeswitch(源代码的根目录) 执行./configure,以便生成必要的Make ...
- selenium 实现浏览器 前进和后退
#coding=utf-8from selenium import webdriver driver = webdriver.Chrome()driver.get("https://www. ...
- mac shell终端编辑命令行快捷键——行首行尾
mac shell终端编辑命令行快捷键——行首行尾 ctrl+a //移到行首ctrl+e //移到行尾===========linux系统用============alt+a //移到光标所在单词首 ...
- unity, stateMachine, change state name
如图,假设wingsLayer下有个state,叫“New State“,现在想给它改名,则一定要保证当前wingsLayer为选中状态,然后才能在Inspector中可以为其改名.否则若当前选中的不 ...
- 关于 AngularJS 的数据绑定
单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别 ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}. 1 <span n ...
- Android从无知到有知——NO.5
今天整一下利用广播实现ip拨号. 这一块主要用到的知识是android四大组件之中的一个的broadcast receiver(广播接收者).那么它接收什么东东呢,就是我们所无谓的一个个的事件,比 ...