一. TStream类
1.1 TStream类概述
20.1.1 TStream对象
TStream对象是能在各种媒介中存储二进制数据的对象的抽象对象。从TStream 对象继承的对象用于在内存、Windows资源文件、磁盘文件和数据库字段等媒
介中存储数据。
TStream中定义了两个属性:Size和Position。它们分别以字节为单位表示的流的大小和当前指针位置。TStream中定义的方法用于在各种流中读、写和相互
拷贝二进制数据。因为所有的Stream对象都是从TStream中继承来的,所以在TStream中定义的域和方法都能被Stream对象调用和访问。此外,又由于面向对象技
术的动态联编功能,TStream为各种流的应用提供了统一的接口,简化了流的使用;不同Stream对象是抽象了对不同存储媒介的数据上的操作,因此,TStream的
需方法为在不同媒介间的数据拷贝提供了最简捷的手段。
1.2 重要方法
1.2.1 Seek方法
声明:function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;
Seek方法将流的当前指针移动Offset个字节,字节移动的起点由Origin指定。如果Offset是负数,Seek方法将从所描述的起点往
流的头部移动。下表中列出了Origin的不同取值和它们的含义:
表1 函数Seek的参数的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
常量 值 Seek的起点 Offset的取值
─────────────────────────────────
SoFromBeginning 0 流的开头 正 数
SoFromCurrent 1 流的当前位置 正数或负数
SoFromEnd 2 流的结尾 负 数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1.2.2 CopyFrom方法
声明:function CopyFrom(Source: TStream; Count: Int64): Int64;
CopyFrom从Source所指定的流中拷贝Count个字节到当前流中,并将指针从当前位置移动Count个字节数,函数返回值是实际拷贝的字节数。值得注意的是:
在CopyFrom中定义了常量,const MaxBufSize = $F000;如果参数Count = 0 ,表示按Source流的大小读取流;如果Count < MaxBufSize,则读取Count大小
的流字节。如果Count > MaxBufSize,则在Buffer中只会保留(Count - MaxBuffSize)的那部分值。如图:
1.2.3 ReadComponent方法
声明:function ReadComponent(Instance: TComponent): TComponent;
ReadComponent方法从当前流中读取由Instance所指定的部件,函数返回所读的部件。ReadComponent在读Instance及其拥有的所有对象时创建了一个
Reader对象并调用它的ReadRootComponent方法。
如果Instance为nil,ReadComponent的方法基于流中描述的部件类型信息创建部件,并返回新创建的部件。
1.2.4 ReadComponentRes方法
声明:function ReadComponentRes(Instance: TComponent): TComponent;
ReadComponentRes方法从流中读取Instance指定的部件,但是流的当前位置必须是由WriteComponentRes方法所写入的部件的位置。ReadComponentRes
首先调用ReadResHeader方法从流中读取资源头,然后调用ReadComponent方法读取Instance。如果流的当前位置不包含一个资源头。ReadResHeader将引发一个
EInvalidImage异常事件。在Classes库单元中也包含一个名为ReadComponentRes的函数,该函数执行相同的操作,只不过它基于应用程序包含的资源建立自己的
流。
1.2.5 Read方法
声明:function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
Read方法从当前流中的当前位置起将Count个字节的内容复制到Buffer中,并把当前指针向后移动Count个字节数,函数返回值是实际读的字节数。如果返回值
小于Count,这意味着读操作在读满所需字节数前指针已经到达了流的尾部。
1.2.6 WriteDescendant方法
声明:procedure WriteDescendant(Instance Ancestor: TComponent);
Stream对象的WriteDescendant方法创建一个Writer对象,然后调入该对象的WriteDescendant方法将Instance部件写入流中。Instance可以是从Ancestor
部件继承的窗体,也可以是在从祖先窗体中继承的窗体中相应于祖先窗体中Ancestor部件的部件。
二. 疑问与解答
2.1 关于类中方法间调用的意图
如图,在TStream类中为了实现Size特性,竟然有三个相似的SetSize方法;他们其中的调用关系如图所示,现在有个疑团就是在VCL中为什么要这样设计呢?
答:其实由于SetSize方法是虚函数,在派生类中可以覆盖此方法。所以,当派生类对象访问Size特性时,就通过SetSize64过程调用过程procedure
SetSize(const NewSize: Int64); overload; virtual;而大家注意此时的调用的SetSize过程其实是派生类覆盖后的过程了。这样就访问到了当前的Size值了。
本文来自博客园,作者:del88,转载请注明原文链接:https://www.cnblogs.com/del88/archive/2013/04/22/3034795.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人