Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
Delphi 2010 Architect
|
String aus TFileStream auslesen funktioniert nicht
30. Dez 2010, 14:10
Hallo,
seit 1h versuche ich krampfhaft den Fehler in einem Programmierversuch zu finden, aber ich entdecke ihn eben nicht.
Ich habe mehrere TPersons, die in einer Datei gespeichert werden. Zunächst nur das Geschlecht, Vor- & Nachname und eine Nummer. Das speichern funktioniert auch alles wunderbar, und das Laden scheinbar auch, allerdings bekomme ich keine String-Variablen (Vor- & Nachname) ausgelesen, warum??
Hier der Code:
uGenealogyProcedures.pas (Hilfs- Unit)
Delphi-Quellcode:
uses
Classes;
procedure StrToStream(AString: String; AStream: TFileStream);
procedure StrFromStream(AString: String; AStream: TFileStream);
implementation
var
Size: Integer;
procedure StrToStream(AString: String; AStream: TFileStream);
begin
Size:= Length(AString);
AStream.Write(Size, SizeOf(Integer));
AStream.Write(AString[1], Size);
end;
procedure StrFromStream(AString: String; AStream: TFileStream);
begin
AStream.Read(Size, SizeOf(Integer));
if Size > -1 then begin
SetLength(AString, Size);
AStream.Read(AString[1], Size);
end;
end;
uGenealogy.pas
Delphi-Quellcode:
uses
Classes, Contnrs, SysUtils, uGenealogyProcedures;
type
TSex = (sMale, sFemale, sUnknown);
TGenealogyEntity = class(TPersistent)
private
fNumber: Integer;
public
property Number: Integer read fNumber write fNumber;
procedure SaveToStream(AStream: TFileStream); virtual;
procedure LoadFromStream(AStream: TFileStream); virtual;
end;
TPerson = class(TGenealogyEntity)
private
fSex: TSex;
fFirstName,
fLastName: String;
public
constructor Create(ASex: TSex; AFirstName, ALastName: String); overload;
property Sex: TSex read fSex write fSex;
property FirstName: String read fFirstName write fFirstName;
property LastName: String read fLastName write fLastName;
procedure SaveToStream(AStream: TFileStream); override;
procedure LoadFromStream(AStream: TFileStream); override;
function GetSex: String;
end;
implementation
procedure TGenealogyEntity.SaveToStream(AStream: TFileStream);
begin
AStream.Write(fNumber, SizeOf(Integer));
end;
procedure TGenealogyEntity.LoadFromStream(AStream: TFileStream);
begin
AStream.Read(fNumber, SizeOf(Integer));
end;
constructor TPerson.Create(ASex: TSex; AFirstName, ALastName: String);
begin
inherited Create;
fSex:= ASex;
fFirstName:= AFirstName;
fLastName:= ALastName;
end;
procedure TPerson.SaveToStream(AStream: TFileStream);
begin
AStream.Write(fSex, SizeOf(TSex));
StrToStream(fFirstName, AStream);
StrToStream(fLastName, AStream);
end;
procedure TPerson.LoadFromStream(AStream: TFileStream);
begin
AStream.Read(fSex, SizeOf(TSex));
StrFromStream(fFirstName, AStream);
StrFromStream(fLastName, AStream);
end;
function TPerson.GetSex: String;
begin
case fSex of
sMale: Result:= 'Mann';
sFemale: Result:= 'Frau';
sUnknown: Result:= 'Unbekannt';
end;
end;
uGenealogyFile.pas
Delphi-Quellcode:
uses
Classes, Contnrs, SysUtils, uGenealogy;
type
TGenealogyFile = class(TObject)
private
fFileName: String;
fPersons: TObjectList;
public
constructor Create;
property FileName: String read fFileName write fFileName;
property Persons: TObjectList read fPersons write fPersons;
procedure SaveToFile(AFileName: String);
procedure LoadFromFile(AFileName: String);
end;
implementation
var
PersonCount, i: Integer;
GenFile: TFileStream;
constructor TGenealogyFile.Create;
begin
inherited Create;
fPersons:= TObjectList.Create;
fPersons.OwnsObjects:= True;
end;
procedure TGenealogyFile.SaveToFile(AFileName: String);
begin
fFileName:= AFileName;
GenFile:= TFileStream.Create(AFileName, fmCreate);
GenFile.WriteBuffer(fPersons.Count, SizeOf(Integer));
for i:= 0 to fPersons.Count - 1 do
TPerson(fPersons.Items[i]).SaveToStream(GenFile);
GenFile.Free;
end;
procedure TGenealogyFile.LoadFromFile(AFileName: String);
var
Person: TPerson;
begin
GenFile:= TFileStream.Create(AFileName, fmOpenRead);
GenFile.ReadBuffer(PersonCount, SizeOf(Integer));
for i:= 0 to PersonCount - 1 do
begin
Person:= TPerson.Create;
Person.LoadFromStream(GenFile);
fPersons.Add(Person);
end;
GenFile.Free;
end;
Und nun noch die Main- Unit.
uMain.pas
Delphi-Quellcode:
procedure TfMain.FormCreate(Sender: TObject);
begin
Stammbaum:= TGenealogyFile.Create;
end;
procedure TfMain.bSavePersonClick(Sender: TObject);
var
Person: TPerson;;
begin
Person:= TPerson.Create(TSex(rgSex.ItemIndex), leFirstName.Text, leLastName.Text);
Stammbaum.Persons.Add(Person);
end;
procedure TfMain.FormDestroy(Sender: TObject);
begin
Stammbaum.Free;
end;
procedure TfMain.miOpenClick(Sender: TObject);
var
i: Integer;
begin
if OpenDialog1.Execute then
begin
Stammbaum.LoadFromFile(OpenDialog1.FileName);
Stammbaum.FileName:= OpenDialog1.FileName;
fMain.Caption:= IntToStr(Stammbaum.Persons.Count) + ' Personen'; // funktioniert
for i:= 0 to Stammbaum.Persons.Count-1 do
ListBox1.Items.Add(TPerson(Stammbaum.Persons[i]).LastName + ', ' + TPerson(Stammbaum.Persons[i]).FirstName +
' (' + TPerson(Stammbaum.Persons[i]).GetSex + ')'); // bis auf das Geschlecht werden keine Namen angezeigt
end;
end;
procedure TfMain.miSaveAsClick(Sender: TObject);
begin
if SaveDialog1.Execute then
Stammbaum.SaveToFile(SaveDialog1.FileName);
end;
procedure TfMain.miSaveClick(Sender: TObject);
begin
if Stammbaum.FileName <> '' then
Stammbaum.SaveToFile(Stammbaum.FileName)
else
miSaveAs.Click;
end;
Vielleicht kann mir bitte einer von Euch helfen. Ich bin ganz irritiert, da ich sonst immer auf diesem simplen Gerüst meine Dateiarbeiten durchführe und bis jetzt nie Probleme damit hatte.
HG hansklok
Geändert von hansklok (30. Dez 2010 um 14:23 Uhr)
|