庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>Delphi语言>基础教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

开发Delphi对象式数据管理功能(六)

 作者:本站收集   日期:2005-3-29
字号选择〖 〗/ 双击滚屏 单击停止   

20.2.2.2 TWriter对象的实现

 

  TWriter对象提供了许多往流中写各种类型数据的方法,这对于程序员来说是很重要的功能。TWrite对象往流中写数据是依据不同的数据采取不同的格式的。 因此要掌握TWriter对象的实现和应用方法,必须了解Writer对象存储数据的格式。

  首先要说明的是,每个Filer对象的流中都包含有Filer对象标签。该标签占四个字节其值为“TPF0”。Filer对象为WriteSignatureReadSignature方法存取该标签。该标签主要用于Reader对象读数据(部件等)时,指导读操作。

  其次,Writer对象在存储数据前都要留一个字节的标志位,以指出后面存放的是什么类型的数据。该字节为TValueType类型的值。TValueType是枚举类型,占一个字节空间,其定义如下:

 

  TValueType = (VaNull, VaList, VaInt8, VaInt16, VaInt32, VaEntended, VaString, VaIdent,

VaFalse, VaTrue, VaBinary, VaSet, VaLString, VaNil, VaCollection);

 

因此,对Writer对象的每一个写数据方法,在实现上,都要先写标志位再写相应的数据;Reader对象的每一个读数据方法都要先读标志位进行判断,如果符合就读数据,否则产生一个读数据无效的异常事件。VaList标志有着特殊的用途,它是用来标识后面将有一连串类型相同的项目,而标识连续项目结束的标志是VaNull。因此,在Writer对象写连续若干个相同项目时,先用WriteListBegin写入VaList标志,写完数据项目后,再写出VaNull标志;而读这些数据时,以ReadListBegin开始,ReadListEnd结束,中间用EndofList函数判断是否有VaNull标志。

  下面就介绍它们的实现。

  1. TWriter对象属性的实现

  TWriter对象直接从TFiler对象继承,它只增加了PositionRootAncestor属性。

RootAncestor属性在private部分有数据FRootAncestor存入其值。在属性定义的读与控制上都是直接读取该值。

  Position属性的定义中包含了两个读写控制方法:GetPositionSetPosition

 

TWriter = class(TFiler)

private

FRootAncestor: TComponent;

function GetPosition: Longint;

procedure SetPosition(Value: Longint);

public

property Position: Longint read GetPosition write SetPosition;

property RootAncestor: TComponent read FRootAncestor write FRootAncestor;

end;

 

GetPositionSetPosition方法实现如下:

 

function TWriter.GetPosition: Longint;

begin

Result := FStream.Position + FBufPos;

end;

 

procedure TWriter.SetPosition(Value: Longint);

var

StreamPosition: Longint;

begin

StreamPosition := FStream.Position;

{ 只清除越界的缓冲区 }

if (Value < StreamPosition) or (Value > StreamPosition + FBufPos) then

begin

WriteBuffer;

FStream.Position := Value;

end

else FBufPos := Value - StreamPosition;

end;

 

  WriteBufferTWriter对象定义的私有方法,它的作用是将Writer 对象内部缓冲区中的有效数据写入流中,并将FBufPos置为0Writer对象的FlushBuffer对象就是用WriteBuffer方法刷新缓冲区。

  在SetPosition方法中,如果Value值超出了边界(FStream.PositionFStream.Position + FBufPos),就将缓冲区中的内容写入流,重新设置缓冲区在流中的相对位置;否则,就只是移动FBufPos指针。

  2. TWriter方法的实现

  ⑴ WriteListBeginWriteListEnd的实现

  这两个方法都是用于写连续若干个相同类型的值。WriteListBegin写入VaList标志,WriteListEnd写入VaNull标志。

 

procedure TWriter.WriteListBegin;

begin

WriteValue(vaList);

end;

 

procedure TWriter.WriteListEnd;

begin

WriteValue(vaNull);

end;

 

  这两个方法都调用TWriter对象的WriteValue方法,该方法主要用于写入TValueType类型的值。

 

procedure TWriter.WriteValue(Value: TValueType);

begin

Write(Value, SizeOf(Value));

end;

 

  ⑵ 简单数据类型的写入

  简单数据类型指的是整型、字符型、字符串型、浮点型、布尔型等。TWriter对象都定义了相应的写入方法。

  WriteInteger方法用于写入整型数据

 

procedure TWriter.WriteInteger(Value: Longint);

begin

if (Value >= -128) and (Value <= 127) then

begin

WriteValue(vaInt8);

Write(Value, SizeOf(Shortint));

end else

if (Value >= -32768) and (Value <= 32767) then

begin

WriteValue(vaInt16);

Write(Value, SizeOf(Smallint));

end else

begin

WriteValue(vaInt32);

Write(Value, SizeOf(Longint));

end;

end;

 

  WriteInteger方法将整型数据分为8位、16位和32位三种,并分别用vaInt8vaInt16VaInt32

  WriteBoolean用于写入布尔型数据

 

procedure TWriter.WriteBoolean(Value: Boolean);

begin

if Value then

WriteValue(vaTrue) else

WriteValue(vaFalse);

end;

 

  与其它数据类型不同的是布尔型数据只使用了标志位是存储布尔值,在标志位后没有数据

  WriteFloat方法用于写入浮点型数据

 

procedure TWriter.WriteFloat(Value: Extended);

begin

WriteValue(vaExtended);

Write(Value, SizeOf(Extended));

end;

 

  字符串“True”、“False”和“nil”作为标识符传入是由于Delphi的特殊需要。如果是“True”、“False”和“nil”则写入VaTrueVaFalseVaNil,否则写入VaIdent标志,接着以字符串形式写入标识符。

  WriteString方法用于写入字符

  

procedure TWriter.WriteString(const Value: string);

var

L: Integer;

begin

L := Length(Value);

if L <= 255 then

begin

WriteValue(vaString);

Write(L, SizeOf(Byte));

end else

begin

WriteValue(vaLString);

Write(L, SizeOf(Integer));

end;

Write(Pointer(Value)^, L);

end;

 

  Delphi字符串类型有两种。一种长度小于256个字节,另一种长度小于65536 个字节。WriteString方法区分这两类情况存储字符串,一种设置VaStirng标志,另一种设置VaLString。然后存储字符串的长度值,最后存储字符数据

  WriteChar方法用于写入字符

  

procedure TWriter.WriteChar(Value: Char);

begin

WriteString(Value);

end;

 

  字符类型的读写是用读写字符串的方法,在读的时候,判断字节数为1时,则为字符型。

  ⑶ 部件的写入

  TWriter对象中与写入部件有关的方法有WriteSignatureWritePrefixWriteComponentWriteDescendantWriteRootComponent

 WriteSignature方法用于往流中写入Filer对象标签。

 

procedure TWriter.WriteSignature;

begin

Write(FilerSignature, SizeOf(FilerSignature));

end;

 

  FilerStgnature字符串常量,其值为“TPF0”,代表对象标签。

  WritePrefix方法用于在写入部件前写入ffInheritedffChildPos标志,这些标志表示部件的继承特征和创建序值特征。

 

procedure TWriter.WritePrefix(Flags: TFilerFlags; AChildPos: Integer);

var

Prefix: Byte;

begin

if Flags <> [] then

begin

Prefix := $F0 or Byte(Flags);

Write(Prefix, SizeOf(Prefix));

if ffChildPos in Flags then WriteInteger(AChildPos);

end;

end;

 

  如果ffChildPos置位,则存入部件在Owner中的创建序值。更详细的信息请参阅TReaderReadPrefix方法。

  WriteComponent方法往流中写入部件。

 

procedure TWriter.WriteComponent(Component: TComponent);

 

function FindAncestor(const Name: string): TComponent;

begin

end;

 

begin

Include(Component.FComponentState, csWriting);

if Assigned(FAncestorList) then

Ancestor := FindAncestor(Component.Name);

Component.WriteState(Self);

Exclude(Component.FComponentState, csWriting);

end;

 

  方法中用ComponentWritState方法写入部件的属性。在写入之前将Component.FComponentState置为csWriting写入完后再将csWriting复位。

  WriteDescendant是根据祖先AAncestor的情况写入部件Root

 

procedure TWriter.WriteDescendent(Root: TComponent; AAncestor: TComponent);

begin

FRootAncestor := AAncestor;

FAncestor := AAncestor;

FRoot := Root;

WriteSignature;

WriteComponent(Root);

end;

 

方法先调用WriteSignature方法写入Filer对象标签。然后调用WriteComponent将部件Root写入流。

  WriteRootComponent方法则是调用WriteDescendant方法写入部件,只是将后者的Ancestor参数以nil值传入。 

procedure TWriter.WriteRootComponent(Root: TComponent);

begin

WriteDescendent(Root, nil);

end;

上一篇:开发Delphi对象式数据管理功能(七)    下一篇:开发Delphi对象式数据管理功能(五)  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-3-29
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿