Delphi文件操作变量的数据保存于内存中,随程序运行的结束而结束,若要使程序下次运行时能重复使用或给其他程序员使用,必须保存在文件中,Delphi存取文件的方式有4种,即传统的PASCAL方式、windows API文件句柄方式、VCL文件流方式、使用类方法方式。
使用类方法方式比较简单,其他三种方式一般的步骤为:(1) 声明文件类型变量;(2) 给文件类型变量指定文件名;(3) 通过文件类型变量打开并且读写文件,必要时进行文件定位;(4) 关闭文件。
1、PASCAL方式访问文件文件是由相同数据类型的数据元素组成的序列,文件可以分为三种类型:文本文件,类型文件,无类型文件。
文本文件中每个数据元素就是一个字符,占有一个字节,并以回车换行符(#13#10)表示每行的结束;类型文件中每个数据元素的数据类型可以是整数、实型记录型等;无类型文件中每个数据元素是一个字节的二进制数。
文件和数组在形式上有些类似,但实质上有诸多不同,主要表现为以下三个方面:(1)数组的元素个数一般是固定的,而文件的长度一般是不定的、随即的;(2)数组元素总是放于内存中,而文件往往存于外存中;(3)数组以“数组名[下标]”的形式访问数组中的任意一个元素,而文件则需要通过文件变量来访问。
1)类型文件例一、Button1按钮将记录数组XS[0..1]写入文件…Stu.dat‟,Button2将…Stu.dat‟读到记录变量X1,X2,然后用消息框输出。
TYPE Stu = RecordXh:integer;Xm:string[20];END;Procedure TForm1.Buttonclick(Sender:TObject);//记录数组写入文件Const xs:array[0..1] of Stu=((Xh:=405;xm:='张三'),(xh:=406,xm:='李四'));Var F:File of Stu;beginAssignFile(F,'Stu.dat');//关联文件ReWrite(F);//打开方式(写)Write(F,xs[0],xs[1]);//将数组写到文件CloseFile(F);end;procedure TForm1.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 TForm1.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,ExtractFilePath(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 :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)例三、Button5将缓冲区BUF中的数据写入无类型文件'abc.txt',Button5将'abc.txt'读到MEMO1,然后用消息框输出。
procedure TForm1.Button5Click(Sender: TObject);varF:file;//定义为无类型文件n:integer;BUF:array[0..127] of Char;beginAssignFile(F,'abc.txt');ReWrite(F,16);//写方式且块的大小为16个字节;FillChar(BUF,Sizeof(BUF),'A');//缓冲区BUF用A填充,共128个字节BlockWrite(F,Buf,9,n); //写入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:array[0..127] of Char;beginAssignFile(F,'abc.txt');Reset(F,16);BlockRead(F,buf,10,n);/读取10块,实际9块closefile(F);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;//打开文件并返回句柄;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指定文件句柄相应的文件;其中fileopen()函数MODE参数的大尅文件方式和共享文件方式常量如下:FmCreate //用指定的文件名创建,若文件已经存在则打开FmOpenRead //只读方式打开,以下都在SYSUNITS中定义FmOpenWrite //只写方式打开FmopenReadWrite //读写方式打开FmShareCompact //DOS兼容模式不可抑制FmshareExclusive //独占方式FmShareDenyWrite //拒绝其他进程写FmShareDenyRead //拒绝其他进程读,不支持所有平台FmShareDenyNone //允许其他进程读或写FileSeek()函数用于改变文件要读写的当前位置,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;begins:=Memo1.Text;Len:=Length(s);n:=1;Hnd:=FileCreate('new.txt'); //创建文件'new.txt'并返回句柄for i:=1 to len do FileWrite(Hnd,s[i],n); //用FOR循环调用FileWrite()函数每次写入N个字符,或FileWrite(Hnd,s[1],len);该方法可一次写入全部字符FileClose(Hnd);end;procedure TForm1.Button8Click(Sender: TObject);varHnd,n:integer;i,len:LongWord;buf:array[0..127] of Char;beginHnd:=FileOpen('new.txt',fMopenRead ); //以只读方式打开文件,并返回该文件的句柄存于Hndlen:=FileSeek(Hnd,0,2);//获取文件的长度(相对于文件尾);i:=0;Memo2.Clear ;While i<len dobeginFileSeek(Hnd,i,0);//定位新读取的位置n:=FileRead(Hnd,Buf,127); //每次读取127个字符i:=i+n; //下次读取位置if n<127 then BUF[n]:=#0;//最后一次读不足127个字符时设置串结束标志Memo2.text:=memo2.Text+buf;//追加到MEMO2中end;end;3、VCL流方式访问文件在面向对象语言中文件的访问逐渐趋向使用数据流来实现,流不仅可以出来文件,还可以处理动态内存、网络数据等多种数据形式。