Q&A

  • TCollection에 대한 고찰...
* 사용환경 : 델파이4 / Windows 98

* 에러 메시지 :



일전에 강좌란에서 TList를 이용하기보다는 TCollection을 이용하는 것이 ReadComponent 및 Writecomponent를 사용할 수 있어 더욱 강력하다는 내용을 접하게 되었습니다.

그런데 문제는 그 강좌란에 있는대로 프로그램을 하니까 실행은 되는데 화일에 저장하고 그 저정된 화일을 읽어서 다시 자료를 복원하는 것이 되지를 않아서 문의를 드립니다.

무엇이 문제인지를 모르겠습니다.

고수님들의 지도를 부탁드립니다.



아래에 내가 응용한 프로그램 소스를 올립니다.



(화일의 내용은 FRealComponent라는 것을 만들어 10개의 실수를 할당하여

Test.dat 화일에 변수명과 변수값을 기록하고, TCollection.dat에 WriteComponent하여

TCollection.dat에 기록된 정보를 ReadComponent하여 읽어들인후 원래의 데이타와 비교하는 것인데 그 결과가 틀림.)



unit Unit1;



interface



uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ComCtrls;



type

TRealComponent = class;



TRealCollectionItem = class( TCollectionItem )

private

FName : String; //Variable Name

FVal : REAL; // Variable Address

procedure SetName( const Value : String );

procedure SetVal( const Value : REAL );

public

property Name : String read FName write SetName;

property Val : REAL read FVal write SetVal;

end;



TRealCollection = class( TCollection )

private

FComponent : TRealComponent;

function GetItem( Index : Integer ) : TRealCollectionItem;

procedure SetItem( Index : Integer; Value : TRealCollectionItem );

protected

public

constructor Create( RealComponent : TRealComponent );

function Add : TRealCollectionItem;

property Items[Index: Integer] : TRealCollectionItem read GetItem write SetItem; default;

end;



TRealComponent = class( TComponent )

private

FItems : TRealCollection;

procedure SetItems( Value : TRealCollection );

public

constructor Create( AOwner : TComponent ); override;

destructor Destroy; override;

published

property Items : TRealCollection read FItems write SetItems;

end;



type

TForm1 = class(TForm)

Save: TButton;

Restore: TButton;

StatusBar1: TStatusBar;

procedure SaveClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure RestoreClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;



var

Form1: TForm1;

alog,crsadj1j,crsadj1jmax, crsadj2j : real;

crsadj2jmax, crsaijk1, crsaijk2, crsail1, crsail2, crsair1 : real;

crsair2, crsajl1, crsajl2, crsajr1, crsajr2, crsakl1, crsakl2 : real;

crsakr1, crsakr2 : real;

FRealComponent : TRealComponent;



procedure SetTList;

procedure AddDataReal( Name : String; Val : REAL);

implementation



{$R *.DFM}



procedure AddDataReal( Name : String; Val : REAL);

var

Soo : TRealCollectionItem;

begin

Soo := FRealComponent.Items.Add;

Soo.Name := Name;

Soo.Val := Val;

end;



////////////////////////////////////////////////////////////////////////////////

// TRealCollectionItem

////////////////////////////////////////////////////////////////////////////////



procedure TRealCollectionItem.SetName( const Value : String );

begin

if FName <> Value then

FName := Value;

end;



procedure TRealCollectionItem.SetVal( const Value : REAL );

begin

if FVal <> Value then

FVal := Value;

end;



////////////////////////////////////////////////////////////////////////////////

// TRealCollection

////////////////////////////////////////////////////////////////////////////////



constructor TRealCollection.Create( RealComponent : TRealComponent );

begin

inherited Create( TRealCollectionItem );

FRealComponent := RealComponent;

end;



function TRealCollection.Add : TRealCollectionItem;

begin

Result := TRealCollectionItem( inherited Add );

end;



function TRealCollection.GetItem( Index : Integer ) : TRealCollectionItem;

begin

Result := TRealCollectionItem( inherited GetItem( Index ) );

end;



procedure TRealCollection.SetItem( Index : Integer; Value : TRealCollectionItem );

begin

inherited SetItem( Index, Value );

end;



////////////////////////////////////////////////////////////////////////////////

//TRealComponent

////////////////////////////////////////////////////////////////////////////////



constructor TRealComponent.Create( AOwner : TComponent );

begin

inherited Create( AOwner );

FItems := TRealCollection.Create( Self );

end;



destructor TRealComponent.Destroy;

begin

FItems.Free;

inherited Destroy;

end;



procedure TRealComponent.SetItems( Value : TRealCollection );

begin

FItems.Assign( Value );

end;



procedure SetTList;

begin

AddDataReal('alog', 1.0);

AddDataReal('crsadj1j', 2.0);

AddDataReal('crsadj1jmax', 3.0);

AddDataReal('crsadj2j', 4.0);

AddDataReal('crsadj2jmax', 5.0);

AddDataReal('crsaijk1', 6.0);

AddDataReal('crsaijk2', 7.0);

AddDataReal('crsail1', 8.0);

AddDataReal('crsail2', 9.0);

AddDataReal('crsair1', 10.0);

end;



// FRealComponent의 내용을 TCollection.dat(이진화일) 과 Test.dat(Ascii화일)에 저장한다.

procedure TForm1.SaveClick(Sender: TObject);

var

Soo : TFileStream;

tmp_str : string;

SFile : TEXTFILE;

m : integer;

begin



// FRealComponent의 내용을 TCollection.dat(이진화일)에 저장한다.

Soo := TFileStream.Create( 'TCollection.Dat', fmCreate );

try

Soo.WriteComponent( FRealComponent );

finally

Soo.Free;

end;



// FRealComponent의 내용을 Test.dat(Ascii화일)에 저장한다.

AssignFile(SFile,'Test.dat');

Rewrite(SFile);



for m := 0 to (FRealComponent.Items.count -1 ) do begin

tmp_str := FRealComponent.Items[m].Name + ' ' + FloatToStr(FRealComponent.Items[m].Val);

WriteLn(SFile, tmp_str);

end;



CloseFile(SFile);



end;



procedure TForm1.FormCreate(Sender: TObject);

begin

FRealComponent := TRealComponent.Create( Self );

SetTList;

end;



// TCollection.dat(이진화일)에 저장된 내용을 FRealComponent에 읽어들인다.

procedure TForm1.RestoreClick(Sender: TObject);

var

Soo : TFileStream;

tmp_str : string;

SFile : TEXTFILE;

m : integer;

FRealComponent1 : TRealComponent;

New: TComponent;

begin



// TCollection.dat(이진화일)에 저장된 내용을 FRealComponent에 읽어들인다.

soo := TFileStream.Create( 'TCollection.Dat', fmOpenRead );

try

FRealComponent := TRealComponent(Soo.ReadComponent( nil ) );

InsertComponent(FRealComponent);

finally

Soo.Free;

end;



// 읽어들인 FRealComponent의 내용을 위의 'Test.dat와 비교하기 위해 'Test1.dat'를 기록한후 비교한다.

// 비교해보면 위의 'Test.dat'와 'Test1.dat'의 내용이 다름을 알수 있게됨.

AssignFile(SFile,'Test1.dat');

Rewrite(SFile);



for m := 0 to (FRealComponent.Items.count -1 ) do begin

tmp_str := FRealComponent.Items[m].Name + ' ' + FloatToStr(FRealComponent.Items[m].Val);

WriteLn(SFile, tmp_str);

end;



CloseFile(SFile);

end;



initialization

RegisterClasses( [TRealComponent] );





end.





0  COMMENTS