问题描述
我有一个TObjectList,我试图写到磁盘。虽然我最终有一个文件(54字节),当我将FNAME属性值更改为真正长的文件,文件的大小从不改变,我得到nil当我尝试读它。我错了什么是错的。对于长代码段很抱歉。它很容易理解发生了什么,只是我不知道为什么它不做我想要的。
类型
{声明一个新的对象类型。 }
TNewObject = class(TComponent)
private
FName:String;
public
属性BizName:String read FName write FName;
constructor Create(const AName:String);
destructor Destroy();覆盖;
end;
为我的TObjectList声明一个全局变量
var
Form1:TForm1;
List:TObjectList< TNewObject> ;;
声明我的构造函数和析构函数。
构造函数TNewObject.Create(const AName:String);
begin
FName:= AName;
end;
destructor TNewObject.Destroy;
begin
inherited;
end;
现在添加一个按钮创建我的对象...
procedure TForm1.CreateButtonClick(Sender:TObject);
var
Obj:TNewObject;
begin
{创建一个新的列表。 }
{OwnsObjects属性默认设置为true - 列表将自动释放拥有的对象。 }
List:= TObjectList< TNewObject> .Create();
{将一些项添加到列表中。 }
List.Add(TNewObject.Create('One'));
List.Add(TNewObject.Create('Two'));
{添加一个新项目,但保留引用。 }
Obj:= TNewObject.Create('Three');
List.Add(Obj);
end;
现在添加一个SAVE按钮
procedure TForm1.SaveButtonClick(Sender:TObject);
var
i:Integer;
fs:TfileStream;
begin
if SaveDialog1.Execute then
begin
fs:= TfileStream.Create(SaveDialog1.FileName,fmCreate);
try
for i:= 0 to List.Count - 1 do
begin
ShowMessage(List [i] .BizName);
fs.WriteComponent(TNewObject(List [i]));
end;
finally
fs.Free;
end;
end;
end;
CAVEATS:我知道只有PUBLIC属性将被保存...应该是BIZNAME。这3个条目显示在SHOWMESSAGE当它被保存....
我记得我的课堂注册。
初始化
RegisterClass(TNewObject);
为了完整起见,这里是我的加载例程...
procedure TForm1.LoadButtonClick(Sender:TObject);
var
i:Integer;
fs:TfileStream;
vRecord:TNewObject;
begin
如果OpenDialog1.Execute然后
begin
List.Clear; // clear list
fs:= TfileStream.Create(OpenDialog1.FileName,fmopenRead);
try
while fs.Position< fs.size do
begin
vRecord:= TNewObject(fs.ReadComponent(nil));
ShowMessage(vRecord.FName);
List.Add(vRecord);
end;
finally
fs.Free;
end;
ShowMessage(IntToStr(List.Count));
end;
end;感谢您的帮助。 >
或者你也可以覆盖 DefineProperties
以决定要传送的内容。
type
TNewObject = class(TComponent )
private
FName:String;
procedure ReadName(Reader:TReader);
procedure WriteName(Writer:TWriter);
protected
procedure DefineProperties(Filer:TFiler);覆盖;
public
属性BizName:String read FName write FName;
...
procedure TNewObject.ReadName(Reader:TReader);
begin
FName:= Reader.ReadString;
end;
procedure TNewObject.WriteName(Writer:TWriter);
begin
Writer.WriteString(FName);
end;
procedure TNewObject.DefineProperties(Filer:TFiler);
begin
inherited;
Filer.DefineProperty('bizname',ReadName,WriteName,FName<>'');
end;
I have a TObjectList, which I am trying to write to disk. Although I end up with a file (54 bytes), when I change the FNAME property value to something really long, the size of the file never changes, and I get nil when I try to read it. I am at a loss as to what is wrong. Sorry for the long code snippet. it is easy to understand what is going on, just I can't figure out why it's not doing what I want.
type
{ Declare a new object type. }
TNewObject = class(TComponent)
private
FName: String;
public
property BizName: String read FName write FName;
constructor Create(const AName: String);
destructor Destroy(); override;
end;
Declare a Global var for my TObjectList
var
Form1: TForm1;
List: TObjectList<TNewObject>;
Declare my constructors and destructors..
constructor TNewObject.Create(const AName: String);
begin
FName := AName;
end;
destructor TNewObject.Destroy;
begin
inherited;
end;
Now add a button to create my objects...
procedure TForm1.CreateButtonClick(Sender: TObject);
var
Obj: TNewObject;
begin
{ Create a new List. }
{ The OwnsObjects property is set by default to true -- the list will free the owned objects automatically. }
List := TObjectList<TNewObject>.Create();
{ Add some items to the List. }
List.Add(TNewObject.Create('One'));
List.Add(TNewObject.Create('Two'));
{ Add a new item, but keep the reference. }
Obj := TNewObject.Create('Three');
List.Add(Obj);
end;
Now add a SAVE Button
procedure TForm1.SaveButtonClick(Sender: TObject);
var
i: Integer;
fs: TfileStream;
begin
if SaveDialog1.Execute then
begin
fs := TfileStream.Create(SaveDialog1.FileName, fmCreate);
try
for i := 0 to List.Count - 1 do
begin
ShowMessage(List[i].BizName);
fs.WriteComponent(TNewObject(List[i]));
end;
finally
fs.Free;
end;
end;
end;
CAVEATS: I know that only PUBLIC properties will be saved... which should be BIZNAME. The 3 entries do show up in the SHOWMESSAGE when it is being saved....
I did remember my Class Registration.
Initialization
RegisterClass(TNewObject);
For completeness sake, here is my Load Routine as well...
procedure TForm1.LoadButtonClick(Sender: TObject);
var
i: Integer;
fs: TfileStream;
vRecord: TNewObject;
begin
if OpenDialog1.Execute then
begin
List.Clear; // clear list
fs := TfileStream.Create(OpenDialog1.FileName, fmopenRead);
try
while fs.Position < fs.size do
begin
vRecord := TNewObject(fs.ReadComponent(nil));
ShowMessage(vRecord.FName);
List.Add(vRecord);
end;
finally
fs.Free;
end;
ShowMessage(IntToStr(List.Count));
end;
end;
Thank you for your help.
解决方案 Component streaming system only streams published properties, you need to publish 'BizName'.
Alternatively you can override DefineProperties
to decide what else to stream.
type
TNewObject = class(TComponent)
private
FName: String;
procedure ReadName(Reader: TReader);
procedure WriteName(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
public
property BizName: String read FName write FName;
...
procedure TNewObject.ReadName(Reader: TReader);
begin
FName := Reader.ReadString;
end;
procedure TNewObject.WriteName(Writer: TWriter);
begin
Writer.WriteString(FName);
end;
procedure TNewObject.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('bizname', ReadName, WriteName, FName <> '');
end;
这篇关于Delphi - 无法保存/加载TObjectList到FileStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-14 22:38