第二十章-开发Delphi对象式数据管理功能(二)(4)

2. Read和Write方法的实现

Read和Write方法都调用BDE API函数完成数据库BLOB字段的读写,其实现如下:

function TBlobStream.Read(var Buffer; Count: Longint): Longint;

var

Status: DBIResult;

begin

Result := 0;

if FOpened then

begin

Status := DbiGetBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, @Buffer, Result);

case Status of

DBIERR_NONE, DBIERR_ENDOFBLOB:

begin

if FField.FTransliterate then

NativeToAnsiBuf(FDataSet.Locale, @Buffer, @Buffer, Result);

Inc(FPosition, Result);

end;

DBIERR_INVALIDBLOBOFFSET:

{Nothing};

else

DbiError(Status);

end;

end;

end;

Read方法使用了BDE API的DbiGetBlob函数从FDataSet中读取数据,在本函数中,各参数的含义是这样的:FDataSet.Handle代表DataSet的BDE句柄,FReacord表示BLOB字段所在记录,FFieldNo表示BLOB字段号,FPosition表示要读的的数据的起始位置,Count表示要读的字节数,Buffer是读出数据所占的内存,Result是实际读出的字节数。该BDE函数返回函数调用的错误状态信息。

Read方法还调用了NativeToAnsiBuf进行字符集的转换。

function TBlobStream.Write(const Buffer; Count: Longint): Longint;

var

Temp: Pointer;

begin

Result := 0;

if FOpened then

begin

if FField.FTransliterate then

begin

GetMem(Temp, Count);

try

AnsiToNativeBuf(FDataSet.Locale, @Buffer, Temp, Count);

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, Temp));

finally

FreeMem(Temp, Count);

end;

end else

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

Count, @Buffer));

Inc(FPosition, Count);

Result := Count;

FModified := True;

end;

end;

Write方法调用了BDE API的DbiPutBlob函数实现往数据库BLOB字段存储数据。

该函数的各参数含义如下:

表20.2 调用函数DbiPutBlob的各传入参数的含义

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

参数名 含义

──────────────────────────────

FDataSetHandle 写入的数据库的BDE句柄

FRecord 写入数据的BLOB字段所在的记录

FFieldNo BLOB字段号

FPosition 写入的起始位置

Count 写入的数据的字节数

Buffer 所写入的数据占有的内存地址

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

方法中还根据FField和FTransliterate的值判断是否进行相应的字符集转换,最后移动BLOB流的位置指针,并将修改标志FModified置为True。

3. Seek和GetBlobSize方法的实现

Seek方法的功能主要是移动BLOB流的位置指针。GetBlobSize方法是私有的,在Seek方法中被调用,其功能是得到BLOB数据的大小。它们的实现如下:

function TBlobStream.GetBlobSize: Longint;

begin

Result := 0;

if FOpened then

Check(DbiGetBlobSize(FDataSet.Handle, FRecord, FFieldNo, Result));

end;

function TBlobStream.Seek(Offset: Longint; Origin: Word): Longint;

begin

case Origin of

0: FPosition := Offset;

1: Inc(FPosition, Offset);

2: FPosition := GetBlobSize + Offset;

end;

Result := FPosition;

end;

GetBlobSize调用了BDE API的DbiGetBlobSize函数,该函数的参数的含义同前面的API函数相同。

时间: 2024-12-21 00:14:54

第二十章-开发Delphi对象式数据管理功能(二)(4)的相关文章

第二十章-开发Delphi对象式数据管理功能(四)(6)

7. SetName方法和OnSetName事件 因为在OnSetName事件中,Name参数是var型的,所以可以用OnSetName事件处理过程修改所读部件的名字.而OnSetName事件处理过程是在SetName方法中实现的. procedure TReader.SetName(Component: TComponent; var Name: string); begin if Assigned(FOnSetName) then FOnSetName(Self, Component, Na

第二十章-开发Delphi对象式数据管理功能(一)-(1)

面向对象技术是九十年代的主流技术,各类应用软件如果以面向对象的方法构造并且渗透面向对象的风格将使软件具有更高的品质.在面向对象程序设计中,对象式数据管理占有很重要的地位.在Delphi中,对对象式数据管理的支持方式是其一大特色. Delphi是一个面向对象的可视化设计与面向对象的语言相结合的集成开发环境.Delphi的核心是部件.部件是对象的一种.Delphi应用程序完全是由部件来构造的,因此开发高性能的Delphi应用程序必然会涉及对象式数据管理技术. 对象式数据管理包括两方面的内容: ● 用

第二十章-开发Delphi对象式数据管理功能(一)-(2)

20.1.1.2 TStream的实现原理 TStream对象是Stream对象的基础类,这是Stream对象的基础.为了能在不同媒介上的存储数据对象,后继的Stream对象主要是在Read和Write方法上做了改进,.因此,了解TStream是掌握Stream对象管理的核心.Borland公司虽然提供了Stream对象的接口说明文档,但对于其实现和应用方法却没有提及,笔者是从Borland Delphi 2.0 Client/Server Suite 提供的源代码和部分例子程序中掌握了流式对象

第二十章-开发Delphi对象式数据管理功能(二)(2)

4. 析构方法Destroy 该方法产生给资源解锁,然后释放该资源,最后调用继承的Destroy方法释放ResourceStream.其实现如下: destructor TResourceStream.Destroy; begin UnlockResource(HGlobal); FreeResource(HResInfo); inherited Destroy; end; 回顾Initialize方法,我们不难发现: ● ResourceStream没有额外地给资源重新分配内存,而是直接使用H

第二十章-开发Delphi对象式数据管理功能(二)(5)

4. Truncate方法 该方法是通过调用BDE API函数实现的.其实现如下: procedure TBlobStream.Truncate; begin if FOpened then begin Check(DbiTruncateBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition)); FModified := True; end; end; 该方法从BLOB流的当前位置起删除所有数据,并设置修改标志FModified为True.在Del

第二十章-开发Delphi对象式数据管理功能(二)(3)

20.1.7.2 TBlobStream的实现原理 说明TBlobStream对象的实现原理,不可避免地要涉及它的私有域,下面是私有域的定义: TBlobStream = class(TStream) private FField: TBlobField; FDataSet: TDataSet; FRecord: PChar; FBuffer: PChar; FFieldNo: Integer; FOpened: Boolean; FModified: Boolean; FPosition: L

第二十章-开发Delphi对象式数据管理功能(二)(1)

20.1.6 TResourceStream对象 TResourceStream对象是另一类MemoryStream对象,它提供对Windows 应用程序资源的访问,因此称它为资源流.TResourceSream也是从TCustomMemoryStream 继承的.因此在TCustomMemoryStream对象的基础上,定义了与指定资源模块或资源文件建立连接的构造方法,并且还覆盖了Write,以实现向资源文件中写数据. 下面介绍TResourceStream的实现 1. 私有域 TResour

第二十章-开发Delphi对象式数据管理功能(五)(4)

3. 动态DFM文件应用之二:超媒体系统脚本语言设计 超媒体脚本语言设计是超媒体系统设计的重要内容.脚本语言必须能够表达卡片中的多种媒体对象,必须是可编程,可理解的,必须是可执行的,应该可以由脚本语言生成超媒体系统中的卡片和链. DFM文件可以看作是超媒体系统的卡片,DFM脚本能够表达DFM文件中的多种控制,也就是说能够表达卡片中的多种媒体对象,再加上DFM脚本的对象式表达,可编辑性,可转换为DFM文件,因此用作超媒体系统脚本语言较好的形式. ObjectBinaryToText和ObjectT

第二十章-开发Delphi对象式数据管理功能(五)(6)

20.3.2.4 BLOB字段与Stream对象 因为Delphi中,BLOB字段是通过BLOB流来访问的,所以可以很容易地在BLOB字段和Stream对象之间传递数据.为此,TBlobField对象提供了LoadFromStream和SaveToStream方法. procedure TBlobField.LoadFromStream(Stream: TStream); var BlobStream: TBlobStream; begin BlobStream := TBlobStream.C