* 사용환경 : 델파이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.