DELPHI基础教程:开发Delphi对象式数据管理功能(二)[1]
TResourceStream对象
TResourceStream对象是另一类MemoryStream对象 它提供对Windows 应用程序资源的访问 因此称它为资源流 TResourceSream也是从TCustomMemoryStream 继承的 因此在TCustomMemoryStream对象的基础上 定义了与指定资源模块或资源文件建立连接的构造方法 并且还覆盖了Write 以实现向资源文件中写数据
下面介绍TResourceStream的实现
私有域
TResourceStream没有定义新的属性 但它在private部分定义了两个数据域HResInfo和HGlobol和一个私有方法Initialize 它们的定义如下
TResourceStream = class(TCustomMemoryStream)
private
HResInfo: HRSRC;
HGlobal: THandle;
procedure Initialize(Instance: THandle; Name ResType: PChar)
…
end;
HRSRC是描述Windows资源信息的结构句柄 HGlobal变量代表资源所在模块的句柄 如果操作的是应用程序资源 HGlohal就代表EXE程序的句柄 如果是动态链接库(DLL) 则HGlobal 代表动态链接库的句柄 TResourceStream对象使用这两上变量访问应用程序或动态链接库中的资源
Initialize方法是TResourceStream对象内部使用的 它的构造方法Create和CreateFromID都是调用Initialize方法完成对TResourceStream的初始化 它的实现如下
procedure TResourceStream Initialize(Instance: THandle; Name ResType: PChar)
procedure Error;
begin
raise EResNotFound Create(FmtLoadStr(SResNotFound [Name]))
end;
begin
HResInfo := FindResource(Instance Name ResType)
if HResInfo = then Error;
HGlobal := LoadResource(Instance HResInfo)
if HGlobal = then Error;
SetPointer(LockResource(HGlobal) SizeOfResource(Instance HResInfo))
end;
该方法实现中 首先调用Windows函数FoundResource得到由参数Instance指定的模块中的名为Name和类型为ResType的资源 然后调用LoadResource将资源调用内存 并返回该资源在内存中的句柄 最后 将该资源复制到ResourceStream中 方法的Instance参数代表要调用的资源所在的模块句柄 模块可以是可执行文件 也可以是动态链接库 如果在读取资源时没在模块中发现要找的资源则产生异常事件
构造方法Create和CreateFromID
这两个方法在实现上没有大的不同 顾名思义 第一个方法是通过资源名构造TResourceStream; 第二个方法通过资源ID构造TResourceStream 而且在实现过程中 它们都调用了Initialize方法 下面是它们的实现
constructor TResourceStream Create(Instance: THandle; const ResName: string;
ResType: PChar)
begin
inherited Create;
Initialize(Instance PChar(ResName) ResType)
end;
constructor TResourceStream CreateFromID(Instance: THandle; ResID: Integer;
ResType: PChar)
begin
inherited Create;
Initialize(Instance PChar(ResID) ResType)
end;
这两个方法中都有Instance参数 该参数值的含义在Insitialize中介绍过
Write方法
TResourceStream的Write方法只完成一件事 就产生这个异常事件 其实现如下
function TResourceStream Write(const Buffer; Count: Longint) Longint;
begin
raise EStreamError CreateRes(SCantWriteResourceStreamError)
end;
从方法实现中可以看到 TSourceStream对象是不允许写数据的 一旦往资源流中写数据将产生异常事件
析构方法Destroy
该方法产生给资源解锁 然后释放该资源 最后调用继承的Destroy方法释放ResourceStream 其实现如下
destructor TResourceStream Destroy;
begin
UnlockResource(HGlobal)
FreeResource(HResInfo)
inherited Destroy;
end;
回顾Initialize方法 我们不难发现
● ResourceStream没有额外地给资源重新分配内存 而是直接使用HGlobal句柄所指 的内存域
● ResourceStream中的资源在流的生存期 始终是Lock状态 因此要根据Windows 的内存使用规则合理安排ResourceStream的使用
● ResourceStream只是用于访问应用程序和动态链接库中的资源的
在Classes在单元中提供了InternalReadComponentRes函数 该函数使用了TResourceStream对象从Delphi应用程序中读取部件 Delphi是将窗体和部件信息放在模块资源的RCDATA段的
TBlobStream对象
从Delphi 数据库开发平台这个意义上说 TBlobStream 对象是个很重要的对象 TBlobStream对象提供了修改TBlobField TBytesField或TVarBytesField中数据的技术 开发者可以象对待文件或流那样在数据库域中读写数据
传统数据库发展的一个重要趋向是往多媒体数据库发展 目前比较著名和流行的数据库都支持多媒体功能 多媒体数据存储中的一大难点是数据结构不规则 数据量大 各大数据库产品是采用BLOB技术解决多媒体数据存储中的问题 Delphi的TBlobStream对象的意义就在于 一方面可以使Delphi应用程序充分利用多媒体数据库的数据管理能力 另一方面又能利用Object Pascal的强大程序设计能力给多媒体数据库提供全方向的功能扩展余地
使用TBlobStream对象可以在多媒体数据库的BLOB字段存储任意格式的数据 一般说来 许多多媒体数据库只能支持图像 语音或者OLE服务器支持的数据 利用TBlobStream则不同 只要是程序能够定义的数据格式 它都能在BLOB字段中读写 而不需要其它辅助工具
TBlobStream用构造方法Create建立数据库域和BLOB流的联接 用Read或Write 方法访问和改变域中的内容 用Seek方法 在域中定位 用Truncate方法删除域中当前位置起所有的数据
TBlobStream的属性和方法
TBlobStream对象从TStream直接继承 没有增添新的属性 它覆盖了Read Write 和Seek方法 提供了对BLOB字段的访问操作 它增添了Truncate方法以实现BLOB字段中的删除操作
Read方法
声明
function Read(var Buffer; Count: Longint) Longint;Read方法从数据库域的当前位置起复制Count个字节的内容到Buffer中 Buffer也必须至少分配Count个字节 Read方法返回实际传输的字节数 因为传输的字节数可能小于Count 所以需要选择符的边界判断
lishixinzhi/Article/program/Delphi/201311/25100