Delphi编程中传统文件操作与面向对象的流文件操作

编程爱好者

Delphi的很多书讲到文件操作时,都是讲的以前Object Pascal的文件管理功能,其实在Delphi中我觉得更有效率的文件管理功能是使用Delphi中的流对象,使用流对象也更加符合面向对象编程的思想。使用流对象进行文件管理,与传统的Object Pascal文件管理相比有哪些优势?Delphi中的流不仅仅可以针对文件管理操作,还可以处理动态内存数据、网络数据、数据库二进制大对象等多种形式的数据。

在Delphi中,Tstream代表所有流的基类,不过它是一个抽象类,它的各子类实现了它并形成了不同功能的流对象,如TFileStream、TBlobStream、TMemoryStream等,其中TFileStream是操作文件的流类,TBlobStream是针对数据库表中二进制大对象字段的流类,TMemoryStream是处理内存数据的流类。利用这些不同的流对象就能完成针对不同数据存储的读取操作。

传统文件管理要求操作文件按照一定的顺序即:打开文件→文件读写→关闭文件。而流对象的操作方式与传统的方式不同,程序员对流进行所有操作,而不用关心流的另一头数据的真正流向,因此大大简化了编写程序的复杂度,使得文件处理对于用户的透明度更高。流不但可以处理文件,还能处理动态内存数据、数据库中的二进制大对象数据、网络数据等多种数据存储形式,如果我们能在程序中利用流的性能,那会改善我们程序的效率。说了这么多流的好处,现在分别介绍一下传统文件操作与流对象操作的异同。

传统文件操作简介:

1.文件类型变量与磁盘文件的关联

函数原型procedure AssignFile(Var F;FileName :String);

F是文件类型变量,FileName表示实际文件名,也可以包括路径。

2.文件的打开

函数原型procedure Reset(Var F[: File; RecSize: Word ]);

F是文件类型变量,其中RecSize表示每次读取记录的字节数。

3.文件的读写操作

读文件函数原型procedure BlockRead(var F: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

写文件函数原型procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

F表示文件类型变量,Buf内存缓冲区,任意类型都可;Count读取记录数目;AmtTransferred表示实际读取或者保存的记录数目,当在正常读取或保存时,该参数返回的值与Count相等。

流对象操作方法简介:

1.流是对象,要使用流对象就必须对其进行实例化,所以它有构造函数

函数原型constructor Create(const FileName: string; Mode: Word); overload;

FileName表示文件名称,也可以包括路径;Mode以怎样的模式创建流的实例。

常用Mode取值及说明如下表:

51-yyzd-b1.jpg

2.CopyFrom函数能从其他流中复制数据

函数原型function CopyFrom(Source: TStream; Count: Int64): Int64;

Source表示要从中复制数据的流对象;Count表示复制的字节数;返回实际复制的字节数。

下面我们举一个文件复制的例子,来看看传统的文件管理方式下与使用流对象方式下的不同之处,并能体会究竟哪种方法更符合面向对象编程的要求、更便捷。

这个例子以复制任意类型的文件为一个指定名称的目标文件,下面是操作详细步骤:

1.建立一个新的工程保存为Project1.dpr。

2.在窗体中放置如下控件

两个Tlabel组件、

两个Tedit组件、四个TButton组件,一个TopenDialog和一个TsaveDialog组件,分别设置组件的属性,界面如图一所示

3.编写“传统方式复制文件”按钮的OnClick事件,代码与注释如下:

procedure TForm1.Button1Click(Sender: TObject);

Var

SourceFile,DestFile :File;

Buf :Array[0..1023] of byte;//内存缓冲区

Reads,Writes :Integer;//分别表示实际读取和写入的字节数

begin

Try

AssignFile(SourceFile,Edit1.Text);//关联源文件

Reset(SourceFile,1);//只读方式打开源文件,并设置每次读取记录的字节数为1字节

AssignFile(DestFile,Edit2.Text);//关联目标文件

Rewrite(DestFile,1);//以可写覆盖方式打开目标文件。

Repeat

BlockRead(SourceFile,Buf,SizeOf(Buf),Reads);//读取源文件SourceFile中的数据,并把每次读取的字节数存入Reads变量中

BlockWrite(DestFile,Buf,SizeOf(Buf),Writes);//写入Buf缓冲区的数据到目标文件DestFile中,并把每次实际写入的字节数存入Writes变量中

Until (Reads=0) or (Reads<>Writes);//当读取的字节数等于0或者实际读取的字节数与实际写入的字节数不相等时,源文件已经到结尾结束文件的读写操作。

finally

CloseFile(SourceFile);

CloseFile(DestFile);//必须关闭使用的文件,避免出现数据丢失

end;

end;

4.编写“流方式复制文件”按钮的OnClick事件,代码与注释如下:

procedure TForm1.Button4Click(Sender: TObject);

Var

SourceStream,DestStream :TFileStream;//定义文件流类型变量

begin

Try

SourceStream :=TFileStream.Create(Edit1.Text,fmOpenRead);//只读方式打开源文件

DestStream :=TFileStream.Create(Edit2.Text,fmCreate);//打开目标文件,如果目标文件存在则打开它

Try

DestStream.CopyFrom(SourceStream,0);//从源文件的流对象中拷贝数据到目的文件的流对象中

Finally

DestStream.Free;

End;

Finally

SourceStream.Free;//释放对象

End;

end;

总结:从上面我们可以看出,使用流对象来操作文件十分的方便而且条理清晰,使用流的效率要高于传统文件操作的方式。并且流在现在的Delphi中已经不仅仅是文件管理操作的替代而已,流对象已经成为了建立在面向对象基础上的一种抽象的数据处理工具,处理能力大大增强,在数据库程序设计、网络数据传输中流的用处十分强大。