注册 登录
编程论坛 Delphi论坛

谁有用TfileTream中读写动态数组的例子?

xu2000 发布于 2007-01-07 12:55, 993 次点击

我想要一份,我写的有错误,调了一天也没搞定。

7 回复
#2
volte2007-01-07 19:06

procedure TForm1.Button1Click(Sender: TObject);
var
FileStream: TFileStream;
Buf: Array Of Byte;
begin
SetLength(Buf,3);
Buf[0] := $AA;
Buf[1] := $AA;
Buf[2] := $AA;

FileStream:= TFileStream.Create('C:\AA.Data',fmCreate);
FileStream.WriteBuffer(Buf[0],3);
FreeAndNil(FileStream);
end;

#3
volte2007-01-07 19:20

procedure TForm1.Button1Click(Sender: TObject);
var
FileStream: TFileStream;
Buf: Array Of Byte;
begin
SetLength(Buf,3);
Buf[0] := $AA;
Buf[1] := $AA;
Buf[2] := $AA;

FileStream:= TFileStream.Create('C:\AA.Data',fmCreate);
FileStream.WriteBuffer(Buf[0],3);//此处可以换成FileStream.Write(Buf, SizeOf(Buf));
FreeAndNil(FileStream);
end;

上面是TFileStream读的方法
至于写就不用发言了吧!

#4
xu20002007-01-09 12:46
先谢谢volte的回答,但我的情况是在读的时个是不知道数组的个数的。我先是声明一个类。

//学习记录
type
TLearn=record
lname:string[40];
atype:string[20];
lntype:string[20];
smint:integer;
sm:array of string[60];
expint:integer;
expstr:array of string[60];
end;

//记录的文件流类

type
TRecFile=class(TFileStream)
private

public
Function AppendRec(Learn:TLearn):boolean; //追加一个记录
Function ReadRec(var Learn:TLearn):boolean; //提取一个记录
procedure SetLearn(ed:Tedit;Comb1,comb2: TComboBox;
Memo1,Memo2: TMemo; var Learn:TLearn); //设置记录值
end;

{******************************************************************

  提取动态数组的方法为
   在数组前加一个字段为该数组的个数,并用循环读入。

******************************************************************}

implementation

//追加一个记录
function TRecFile.AppendRec(Learn:TLearn):boolean;
begin
try
self.Seek(0,soFromEnd);
self.Write(Learn,sizeof(learn));
result:=True;
except
result:=False;
end;
end;

//提取一个记录
function TRecFile.ReadRec(var Learn:TLearn):boolean;
var
i:integer;
begin
try
// self.Seek(0,0);
self.Read(learn.lname,length(learn.lname));
self.Seek(sizeof(learn.lname),soFromCurrent);
self.Read(learn.atype,length(learn.atype));
self.Seek(sizeof(learn.atype),soFromCurrent) ;
self.Read(learn.lntype,20);
self.Seek(sizeof(learn.lntype),1);
self.Read(learn.smint,4);
self.Seek(sizeof(learn.smint),1);
//提取动态数组
if learn.smint>0 then
begin
setlength(learn.sm,learn.smint);
for i:=0 to learn.smint-1 do
begin
self.Read(learn.sm[i],length(learn.sm[i]));
self.Seek(sizeof(learn.sm[i]),1);
end;
end;
self.Read(learn.expint,sizeof(learn.expint));
if learn.expint>0 then
begin
setlength(learn.expstr,learn.expint);
for i:=0 to learn.expint-1 do
begin
self.Read(learn.expstr[i],length(learn.expstr[i]));
self.Seek(sizeof(learn.expstr[i]),1);
end;
end;
result:=false;
except
result:=true;
end;
end;

procedure TRecFile.SetLearn(ed:Tedit;Comb1,comb2: TComboBox;
Memo1,Memo2: TMemo;var Learn:TLearn);
var
i:integer;
begin
learn.lname:=ed.Text;
learn.atype:=comb1.Text;
learn.lntype:=comb2.Text;
learn.smint:=memo1.Lines.Count;
setlength(learn.sm,learn.smint);
if learn.smint>0 then
begin
for i:=0 to learn.smint-1 do
learn.sm[i]:=memo1.Lines.Strings[i];
end;
learn.expint:=memo2.Lines.Count;
setlength(learn.expstr,learn.expint);
if learn.expint>0 then
begin
for i:=0 to learn.expint-1 do
learn.expstr[i]:=memo2.Lines.Strings[i];
end;
end;
#5
xu20002007-01-09 12:50
下面是调用的时的代码。
procedure TForm1.Button1Click(Sender: TObject);
var
mydata:TLearn;
myfile:TRecFile;
begin
try
myfile:=TRecFile.Create('d:\me.xu',fmCreate);
myfile.SetLearn(edit1,combobox1,combobox2,memo1,memo2,mydata);
myfile.AppendRec(mydata);
finally
myfile.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
mydata:TLearn;
myfile:TRecFile;
begin
if myfile=nil then
myfile:=TRecFile.Create('d:\me.xu',fmOpenRead);
myfile.ReadRec(mydata);
edit1.Text:=mydata.lname;
combobox1.Text:=mydata.atype;
combobox2.Text:=mydata.lntype;
for i:=0 to mydata.smint-1 do
memo1.Lines.Add(mydata.sm[i]);
for i:=0 to mydata.expint-1 do
memo1.Lines.Add(mydata.expstr[i]);
end;
但我发现在读的时候,读出来的不正确。而且有时对同一个文件,两次文件两次读出来的数来不一样。这是为什么?
#6
volte2007-01-10 10:41

Record类型运用在函数参数时候要注意,尽量使用指针传递!
要么就转换为类来使用
因为对象的内存一般是由全局堆来分配的.
而record类型中临时变量是由栈来分配.其余可能是由自定义的内存堆分配()!
自定义的内存堆可一次性释放!!

所以要注意Record临时变量的问题!

#7
volte2007-01-10 11:08

而且你用的都是局部变量. 没使用一次,就应该释放一次!

程序的健壮性上还有一定的缺憾!

#8
xu20002007-01-10 11:46
变量的释放问题我已经了解。
上述的代码中并非最终的代码,我只是做的试验,将来还要修改完整。但问题是实验很不成功。
1