在设计数据库的过程中,我们会经常要存储一些图形、长文本、多媒体(视频、音频文件)等各种各样的程序文件,如果我们在数据库中仅存储这些文件的路径信息,尽管这可以大大地减小数据库的大小,但是由于文件存在磁盘上,我们除了维护数据库外还要维护文件的路径信息,保持二者的一致,这对于我们管理数据库非常不方便。我们还是寄希望能够把这些文件的内容作为一个记录的一个字段值存到数据库中,这样文件的上传和下载就变成了简单的字段读写。我们不用再考虑这些文件是如何在磁盘上存储的,数据库会帮我们做好一切工作。 
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 数据库存取二进制文件图象的更多相关文章

  1. 数据库存取缓冲区的LRU与MRU算法

    数据库存取缓冲区的LRU与MRU算法 1.Cache Hit and Cache Miss 当使用者第一次向数据库发出查询数据的请求的时候,数据库会先在缓冲区中查找该数据,如果要访问的数据恰好已经在缓 ...

  2. .NET基础拾遗(6)ADO.NET与数据库开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

  3. ADO访问Access数据库错误解决心得随笔

    最近在用ADO访问Access数据库的时候出现了一个奇怪的错误,觉得有必要记录下来,和大家分享一下. 环境 win7 x86系统: VS2012编译器: Office2010: Access2000~ ...

  4. ado无法访问数据库问题

    现象:以ADO方式访问数据库的C++程序,在一台计算机上能访问成功,在另一台计算机上却访问不成功,报告不能连接错误,并且这两台计算机都装有ado. 原因:ado版本不对 解决方案:下载KB983246 ...

  5. 浅析ado.net获取数据库元数据信息 DeriveParameters

    写这个文章源于早先对ADO.Net获取数据库元数据上的认识,去年我在阅读ADO.Net Core Reference的时候曾经注意过DataSet的FillSchema的这个方法.这方面,在我之前的随 ...

  6. Android sqlite数据库存取图片信息

    Android sqlite数据库存取图片信息 存储图片:bitmap private byte[] getIconData(Bitmap bitmap){ int size = bitmap.get ...

  7. .NET基础拾遗(8)ADO.NET与数据库开发基础

    1.1 ADO.NET支持哪几种数据源? ① System.Data.SqlClient .NET程序员最常用的了.通过OLEDB或者ODBC都可以访问,但是SqlClient下的组件直接针对MSSQ ...

  8. MFC,ADO方式实现数据库操作

    参考: MSDN数据访问编程 (MFC/ATL): https://msdn.microsoft.com/zh-cn/library/kd4ck1tt.aspx?f=255&MSPPError ...

  9. MySQL数据库--思维导图

    MySQL数据库--思维导图

随机推荐

  1. 【LeetCode】114. Flatten Binary Tree to Linked List

    Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. For ex ...

  2. 导入项目出现: Unable to resolve target ‘android-10′ 解决办法

    进入到android项目根目录下,打开项目文件project.properties ,修改 target=android-10  的值.把10改为当前虚拟机API level的版本即可.我这里改为17 ...

  3. SQL SERVER 2005允许自定义聚合函数

    不多说了,说明后面是完整的代码,用来将字符串型的字段的各行的值拼成一个大字符串,也就是通常所说的Concat 例如有如下表dict  ID  NAME  CATEGORY  1 RED  COLOR  ...

  4. 用Reflector for .NET反编译dll文件(.net),把整个dll导出个cs插件

    Reflector for .NET 下载地址: http://www.aisto.com/roeder/dotnet/ Reflector.FileDisassembler.zip下载地址: htt ...

  5. oracle 错误码查看命令oerr ora及常用错误码总结--不断更新

    oracle 错误码查看命令oerr ora及常用错误码总结--不断更新 1.ORA-00907: 缺失右括号 我自己的问题出在 字段的default 和 not null 顺序反了,defalut ...

  6. Java 枚举(enum) 的常见用法和开发规范

    JDK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static final ...

  7. dom写xml

    1.引入包 import xml.dom.minidom 2.writexml方法 writexml(writer, indent, addindent, newl, encoding) writer ...

  8. xcode下build release版本号的.a库

    1. 点击房子 图标button watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlmZGl6dW8=/font/5a6L5L2T/fontsize/40 ...

  9. App Extension的脱壳办法

    App Extension的脱壳办法 从app store下载的app和app extension是加过密的,可以通过otool查看: $ otool -l binary_name | grep cr ...

  10. eclipse配置 嵌入式-基于linux

    Eclipse可以安装在各种操作系统.这里是安装到Ubuntu 10.10上.有两种方法实现安装,一是采用Ubuntu的软件源:二是从官方下载后解压. 1.  通过Ubuntu软件源安装 $ sudo ...