Delphi - невозможно сохранить/загрузить TObjectList в FileStream

У меня есть TObjectList, который я пытаюсь записать на диск. Хотя я получаю файл (54 байта), когда я меняю значение свойства FNAME на что-то очень длинное, размер файла никогда не меняется, и я получаю nil, когда пытаюсь его прочитать. Я в недоумении, что не так. Извините за длинный фрагмент кода. легко понять, что происходит, просто я не могу понять, почему он не делает то, что я хочу.

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;

Объявить глобальную переменную для моего TObjectList

var
  Form1: TForm1;
  List: TObjectList<TNewObject>;

Объявите мои конструкторы и деструкторы.

constructor TNewObject.Create(const AName: String);
begin
  FName := AName;            
end;

destructor TNewObject.Destroy;
begin      
  inherited;
end;

Теперь добавьте кнопку для создания моих объектов...

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;

Теперь добавьте кнопку СОХРАНИТЬ

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;

ОСТОРОЖНО: я знаю, что будут сохранены только ОБЩЕСТВЕННЫЕ свойства... которые должны быть BIZNAME. 3 записи отображаются в СООБЩЕНИИ ОТОБРАЖЕНИЯ, когда оно сохраняется....

Я действительно помнил свою регистрацию класса.

Initialization
RegisterClass(TNewObject); 

Для полноты картины, вот моя процедура загрузки...

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;

Спасибо за помощь.


person user1009073    schedule 10.11.2014    source источник


Ответы (1)


Система потоковой передачи компонентов передает только опубликованные свойства, вам необходимо опубликовать «BizName».

В качестве альтернативы вы можете переопределить DefineProperties, чтобы решить, что еще транслировать.

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;
person Sertac Akyuz    schedule 10.11.2014