2014-11-10 1 views
1

디스크에 쓰려고하는 TObjectList가 있습니다. 파일 (54 바이트)로 끝나지 만, FNAME 속성 값을 실제로 길게 변경하면 파일 크기가 변경되지 않고 읽으려고 할 때 아무 것도 얻지 못합니다. 나는 무엇이 잘못되었는지를 놓치고있다. 긴 코드 스 니펫을 유감스럽게 생각합니다. 무슨 일이 일어나고 있는지 이해하기 쉽습니다. 왜 내가 원하는 것을하지 않는지 알 수 없습니다. Delphi - TObjectList를 FileStream에 저장 /로드 할 수 없습니다.

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; 

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

destructor TNewObject.Destroy; 
begin  
    inherited; 
end; 

지금 내 개체를 만들 수있는 버튼을 추가 ... 내 TObjectList와

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

내 생성자와 소멸자를 선언하기위한 글로벌 VAR를 선언

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; 

이제 SAV를 추가하십시오. E 버튼

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 개의 항목이 SHOWMESSAGE에 표시됩니다.

클래스 등록이 기억났습니다. 완성도를 위해서

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; 

는 당신의 도움을 주셔서 감사합니다 ...뿐만 아니라 내 부하 루틴입니다.

답변

2

구성 요소 스트리밍 시스템은 게시 된 속성 만 스트리밍하므로 '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;