1、Delphi 文件操作变量的数据保存于内存中,随程序运行的结束而结束,若要使程序下次运行时能重复使用或给其他程序员使用,必须保存在文件中,Delphi 存取文件的方式有 4 种,即传统的PASCAL 方式、windows API 文件句柄方式、VCL 文件流方式、使用类方法方式。使用类方法方式比较简单,其他三种方式一般的步骤为:(1) 声明文件类型变量;(2) 给文件类型变量指定文件名;(3) 通过文件类型变量打开并且读写文件,必要时进行文件定位;(4) 关闭文件。1、PASCAL 方式访问文件文件是由相同数据类型的数据元素组成的序列,文件可以分为三种类型:文本文件,类型文件,无类型文件。文本
2、文件中每个数据元素就是一个字符,占有一个字节,并以回车换行符(#13#10)表示每行的结束;类型文件中每个数据元素的数据类型可以是整数、实型记录型等;无类型文件中每个数据元素是一个字节的二进制数。文件和数组在形式上有些类似,但实质上有诸多不同,主要表现为以下三个方面:(1)数组的元素个数一般是固定的,而文件的长度一般是不定的、随即的;(2)数组元素总是放于内存中,而文件往往存于外存中;(3)数组以“数组名 下标”的形式访问数组中的任意一个元素,而文件则需要通过文件变量来访问。1)类型文件例一、Button1 按钮将记录数组 XS01写入文件Stu.dat,Button2 将Stu.dat 读到
3、记录变量 X1,X2,然后用消息框输出。TYPE Stu = RecordXh:integer;Xm:string20;END;Procedure TForm1.Buttonclick(Sender:TObject);/记录数组写入文件Const xs:array01 of Stu=(Xh:=405;xm:=张三),(xh:=406,xm:=李四);Var F:File of Stu;beginAssignFile(F,Stu.dat);/关联文件ReWrite(F);/打开方式(写)Write(F,xs0,xs1);/将数组写到文件CloseFile(F);end;procedure TFo
4、rm1.Button2Click(Sender: TObject);VarF:File of Stu;x1,x2:Stu;beginAssignFile(F,Stu.dat);ReSet(F); /打开方式(读)Read(F,x1,x2); /从文件中读到记录CloseFile(F);/关闭 F 指定文件showmessageFmt(%d,%s;%d,%s,x1.xh,x1.xm,x2.xh,x2.xm);end; 2)文本文件例二、Button3 将 EDIT1 指定库名写入文件DBN.txt,Button4 将 DBN.txt 读到变量 DBN,然后用消息框输出。procedure TFo
5、rm1.Button3Click(Sender: TObject);VarF:TextFile;DBN:string;beginDBN:=edit1.text;AssignFile(F,ExtractFilePath(Application.ExeName)+DBN.txt);Rewrite(F);Writeln(F,DBN);/写入一行字符创到变量 DBNCloseFile(F);end;procedure TForm1.Button4Click(Sender: TObject);VarF:textfile;DBN:string;beginAssignFile(F,ExtractFilePa
6、th(Application.ExeName)+DBN.txt);ReSet(F);Readln(F,DBN);/读取一行字符创到变量 DBNCloseFile(F);Showmessage(DBN);end;注意:有类型文件操作的函数一般有:read 函数,write 函数,EOF 函数:判断文件是否结束;而文本文件除了这些函数之外还有 readln 函数:读取一行字符串,writeln 函数:写一行字符串,EOLN:判断是否为文件行尾,Append 函数,以追加方式打开文件。 3)无类型文件通过文件数据块和写入数据块的过程原型说明如下:procedure BlockRead(Var F :
7、File;const buf;Count:integer;var Result:integer);procedure BlockWrite(Var F :File;const buf;Count:integer;var Result:integer);/参数 BUF 为要读取或写入的数据缓冲区,COUNT 为读或写的数据块的数目;/Result 返回实际读或写如的数据;/数据块的大小默认为 128 个字节,调用 RESET 和 REWRITE 可以设置参数指定读入或写入的字节个数;读取位置定位的过程原型说明如下:procedure seek(var F:file;N:Longint)例三、Bu
8、tton5 将缓冲区 BUF 中的数据写入无类型文件abc.txt,Button5 将abc.txt 读到MEMO1,然后用消息框输出。procedure TForm1.Button5Click(Sender: TObject);varF:file;/定义为无类型文件n:integer;BUF:array0127 of Char;beginAssignFile(F,abc.txt);ReWrite(F,16);/写方式且块的大小为 16 个字节;FillChar(BUF,Sizeof(BUF),A);/缓冲区 BUF 用 A 填充,共 128 个字节BlockWrite(F,Buf,9,n);
9、 /写入 9 块,末尾 16 个字符为乱码CloseFile(F); /写完文件后文件大小为 9*16=144 字节Showmessage(写入的块的个数为:+inttostr(n); /输出为 9,但有效的为 8 块*16=128 个字节end;procedure TForm1.Button6Click(Sender: TObject);VarF:file;n:integer;BUF:array0127 of Char;beginAssignFile(F,abc.txt);Reset(F,16);BlockRead(F,buf,10,n);/读取 10 块,实际 9 块closefile(F
10、);Showmessage(inttostr(n);Memo1.Lines.Add(buf); /有效字符 8 块,128 个字符end;2、Windows API 方式访问文件使用 WINDOW 提供的 API 函数通过句柄也可以访问文件,他们在 DELPHI 中的SysUnit 单元中的定义如下:function FileCreate(const FileName:string;Rights:integer):integer;/创建新文件并返回句柄;function FileOpen(const File Name:string;Mode:LongWord):integer;/打开文件并返
11、回句柄;function FileRead(Handle:integer;VarBuf;Count:LongWord):integer;/从文件中读取数据;function FileWrite(Handle:integer;const buf;Count:Longword):integer;/将数据写入文件;function FileSeek(Handle:integer;const offsetLint64;origin:integer):int64;/读写位置的定位;procedur FileClose(Handle:integer);/关闭 Handle 指定文件句柄相应的文件;其中 f
12、ileopen()函数 MODE 参数的大尅文件方式和共享文件方式常量如下:FmCreate /用指定的文件名创建,若文件已经存在则打开FmOpenRead /只读方式打开,以下都在 SYSUNITS 中定义FmOpenWrite /只写方式打开FmopenReadWrite /读写方式打开FmShareCompact /DOS 兼容模式不可抑制FmshareExclusive /独占方式FmShareDenyWrite /拒绝其他进程写FmShareDenyRead /拒绝其他进程读,不支持所有平台FmShareDenyNone /允许其他进程读或写FileSeek()函数用于改变文件要读写
13、的当前位置,OFFSET 参数用于设置该变量,ORIGIN参数用于设置改变的相对位置,当 ORIGIN 为 0 时意味着 OFFSET 移动的字节数相对于文件头,为 1 时意味着相对于当前位置,为 2 时意味着 OFFSET 相对于文件尾,一般返回相对于文件头的心的当前位置,若返回-1 表示发生异常。例四、BUTTON7 将 MEMO1 中文本写入文件new.txt,button8 将new.txt内容读到 MEMO2中;procedure TForm1.Button7Click(Sender: TObject);varHnd,n:integer;s:string;Len,i:Longint;
14、begins:=Memo1.Text;Len:=Length(s);n:=1;Hnd:=FileCreate(new.txt); /创建文件new.txt并返回句柄for i:=1 to len do FileWrite(Hnd,si,n); /用 FOR 循环调用 FileWrite()函数每次写入 N 个字符,或 FileWrite(Hnd,s1,len);该方法可一次写入全部字符FileClose(Hnd);end;procedure TForm1.Button8Click(Sender: TObject);varHnd,n:integer;i,len:LongWord;buf:arra
15、y0127 of Char;beginHnd:=FileOpen(new.txt,fMopenRead ); /以只读方式打开文件,并返回该文件的句柄存于Hndlen:=FileSeek(Hnd,0,2);/获取文件的长度(相对于文件尾) ;i:=0;Memo2.Clear ;While ilen dobeginFileSeek(Hnd,i,0);/定位新读取的位置n:=FileRead(Hnd,Buf,127); /每次读取 127 个字符i:=i+n; /下次读取位置if n127 then BUFn:=#0;/最后一次读不足 127 个字符时设置串结束标志Memo2.text:=memo
16、2.Text+buf;/追加到 MEMO2 中end;end;3、VCL 流方式访问文件在面向对象语言中文件的访问逐渐趋向使用数据流来实现,流不仅可以出来文件,还可以处理动态内存、网络数据等多种数据形式。数据流(stream)是一组有顺序的、有起点和终点的字节集合,是对数据传输的总称( 或抽象)。数据流有读写两个方向,由外设到内存为读,由内存到外设为写。每个数据流都有一个缓冲区以提高传输效率。TStream 类是所有流的基类,其中定义了所有流的共同属性和方法,其主要属性如下:(1)position: 控制当前流中存取指针的位置;(2)size :指定一次读写流数据的字节数;在 TSTREAM
17、中定义的方法有两类:一类是虚方法,这些方法在其子类中通常被覆盖,以处理不同存储方式的数据,而在使用流时,则不必使用这些方法;另一类是静态方法,如 COPyFORM,这些方法利用虚方法对流进行不同的操作。TSTREAM 中定义的方法主要有以下几种:(1) read :读取指定书目的字节到缓冲区,并自动控制流指针的位置,原型说明如下:function read(var:Buffer,Count:Longint):Longint:virtual;abstrcact;/读 Count 字节到BUFFER;(2) Write:向流中写入数据,并自动控制流指针的位置,原型说明如下:function Wri
18、te(Const Buffer;Count:Longint):Longint;virtual;abstrat;/将 OUNT 字节写到BUFFER;(3) SEEK 方法:将文件流指针安 ORIGIN 指定位置移到 OFFSET 指定的字节数,原型说明如下:function seek(offset:Longint;origin:word):Longint;overload;virtual;/参数意义同 API 句柄方式;(4) CopyFrom 方法:从 Source 流复制 COUNT 字节的数据到当前流,若 COUNT=0;则表示复制所有数据,原型说明如下:function CopyFro
19、m(Source:Tstream;Count:int64):int64;由于 TSTREAM 类的方法是虚方法,所有在其拍摄类中必须覆盖相应的方法,常用的派生类有如下几种;(1) TFileStream:文件操作流,用于已知文件名的文件访问(2) TStringStream 字符串流,用于内存字符串的操作(3) TMemoryStream 内存流,用于管理内存的地址(4) TBlobStream 块操作流面对 BLOB 类进行操作(5) TWinSocketStream 用于以 SOCKET 方式连接的数据流的读写操作(6) TOleStream 用于 COM 接口的读写操作用 TFileSt
20、ream 类进行文件存取要经过 4 个步骤:定义 TFileStreanm 类对象;创建类对象并指定文件名和打开方式;引用类方法进行文件操作;释放类对象。例五、Button9 将 MEMO3 内容读入xx.txt,BUTTON10 将 xx.txt的内容读到 MEMO4。procedure TForm1.Button9Click(Sender: TObject);varF:TFileStream;i:integer;s:string;beginF:=TFileStream.Create(xx.txt,fmCreate);/创建类对象S:=memo3.Text;for i:=1 to lengt
21、h(s) do F.Write(Si,1);/memo3.lines.savetostream(F);直接将 MEMO3 的数据写入流中F.free;end;procedure TForm1.Button10Click(Sender: TObject);varF:TFileStream;len,i:integer;n:LongInt;Buf:array0127 of char;beginF:=TFileStream.Create(xx.txt,fmOpenRead);/Meno4.lines.loadFromStrean(F);用类方法要简单很多len:=F.Seek(0,2);memo4.C
22、lear ;i:=0;while ilen dobeginF.Seek(i,0);n:=F.Read(Buf,127);i:=i+n;if n127 then bufn:=#0;Memo4.Text:=memo4.Text+buf;end;end;用数据流和 STRING 类型直接实现例六、BUTTON11 将 MEMO3 内容读入xx.txt,BUTTON12 将xx.txt 的内容读到 MEMO4。procedure TForm1.Button11Click(Sender: TObject);varF:TFileStream;S:string;beginF:=TFileStream.Cre
23、ate(xin.txt,fmCreate);S:=memo3.Text;F.Write(pointer(s),Length(s);F.Free;end;procedure TForm1.Button12Click(Sender: TObject);varF:TFileStream;s:string;beginF:=TFileStream.Create(xin.txt,fmOpenRead);SetString(s,nil,F.SIZE); /用 HELP 可以查看其功能,在此为设置变量 S 的长度为 F.sizeF.Read(pointer(s),F.size);memo4.text:=s;F
24、.free;end;4、使用类方法访问文件Delphi 在与文件有关的类中都定义了存取文件的方法,使用这些方法可以简单地实现将类中数据保存到文件中或从文件中读取数据到类。根据调用参数的不同又分为两类,其实两者都是通过刘实现的。(1)以字符串作为调用参数的文件存取:LoadFromFile()和 SaveToFile(),原型说明如下:procedure LoadFromFile/SaveToFile(const FileName:string);/从 FileName 指定的文件中读取数据/讲类型写到 FileName 指定的文件中(2) 以流作为调用参数的文件存取:LoadFromStrea
25、m()和 SaveToStream 原型说明如下:Procedure LoadFromStream/SaveToStream(Stream:TStream);在 TStrings、 TGraphi 、TPicture 类或派生类中都定义了以上四个方法,可方便地实现文件的存取,如 TMEMO 类中的 LINES 属性就定义了文件存取方法。5、与文件目录相关的过程和函数 文件操作中除可用文件管理组件和通用对话框组件外,还可以使用标准过程和函数来获取或设置文件和目录有关的信息。1)目录操作(1) 获取当前目录 GetDir(D:byte;var S:string);/读取 D:当前目录到变量 S 中
26、;(2) 新建目录 procedure MKDir(const s:sring);创建 S 指定目录(3) 改变当前目录 procedure ChDir(const s:string); 进入 S 指定目录(4) 删除子目录 procedure RmDir(const s:sring);删除 S 指定目录2)与文件操作有关的过程和函数function CetCurrentDir:string;/返回当前盘当前目录路径那个function SetCurrentDir(const Dir:string):Boolean;/设置当前目录路径,成功返回 TRUEfunction FileExists(
27、const filename:string):Boolean;/判断文件是否存在function DirectoryExists(const Directory:sring):Boolean;/判断目录是否存在function CreateDir(const Dir:string):Boolean;/创建子目录function ExtractFileDir(const filename:string):string;/从文件中提取路径名function ReName(const oldName,NewName:string):Boolean;/文件改名function DeleteFile(Const Filename:string):Boolean;/删除指定文件function FileGetAttr(const filename:string):integer;/返回文件的属性function DiskSize(Drive:Byte):int64;/返回指定盘的总容量