Einzelnen Beitrag anzeigen

Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#24

AW: Eine lineare Liste an Strings als Datei speichern

  Alt 15. Nov 2013, 10:34
Eine seperate Klasse TStorage zum Speichern läuft letztendlich auf ein Visitor-Pattern hinaus.
Damit scheint aber der TE noch leicht überfordert zu sein.
Deshalb erst mal ein einfacher Lösungsansatz, der zwar nicht so universell aber dafür einfacher zu verstehen ist.

Wie speichert man eine Liste von Elementen in einer Datei?
Es gibt verschiedene Dateiformate die sich je nach Anwendungsfall unterschiedlich gut eignen.
Eine einfache Variante ist die CSV-Datei, dabei wird für jedes Element eine Zeile gespeichert. Jede Zeile wird mit Zeilenabschluss beendet (z.B. CRLF).
Innerhalb der Zeile sind die einzelnen Eigenschaften z.B. durch Komma getrennt.
Delphi-Quellcode:
TVokabel = class
  {...}
public
  function ObjectToCSV: string;
  procedure ObjectFromCSV(const AValue: string);
end;

TListe = class
  {...}
public
  procedure Clear;
  procedure SaveToStream(AStream: TStream);
  procedure ReadFromStream(AStream: TStream);
end;

function GetNextString(var AValue: string; const ASeperator): string;
var
  i, n: Integer;
begin
  n := Length(ASeperator);
  i := Pos(ASeperator, AValue);
  if i > 0 then
  begin
    Result := Copy(AValue, 1, i - 1);
    AValue := Copy(AValue, i + n, Length(AValue) - i - n + 1);
  end
  else
  begin
    Result := AValue;
    AValue := '';
  end;
end;

function TVokabel.ObjectToCSV: string;
begin
  Result := Deutsch + ',' + Englisch;
end;

procedure TVokabel.ObjectFromCSV(const AValue: string);
var
  s: string;
begin
  s := AValue;
  Deutsch := GetNextString(s, ',');
  Englisch := GetNextString(s, ',');
end;


procedure TListe.SaveToStream(AStream: TStream);
var
  vokabel: TVokabel;
  s: string;
begin
  vokabel := Erste;
  if Assigned(vokabel) then
  begin
    repeat
      s := vokabel.ObjectToCSV + #13#10;
      AStream.WriteBuffer(PChar(s)^, Length(s));
 
      vokabel := vokabel.naechste;
    until (vokabel = Erste);
  end;
end;

procedure TListe.ReadFromStream(AStream: TStream);
var
  sBuffer, s: string;
  vokabel: TVokabel;
begin
  Clear;
  SetLength(sBuffer, AStream.Length);
  AStream.ReadBuffer(PChar(sBuffer)^, Length(sBuffer));
  while Length(sBuffer) > 0 do
  begin
    s := GetNextString(sBuffer, #13#10);
    if Length(s) > 0 then
    begin
      vokabel := TVokabel.Create;
      vokabel.ObjectFromCSV(s);
      hinzufuegen(vokabel);
    end;
  end;
end;

stream := TFileSream.Create('MyFile.csv', fmCreate);
MyListe.SaveToStream(stream);
stream.Free;

stream := TFileSream.Create('MyFile.csv', fmRead);
MyListe.ReadFromStream(stream);
stream.Free;
Ich habe hier bewusst auf den Einsatz einer TStringList verzichtet. Wenn der TE diese Klasse und deren Möglichkeiten nicht kennt, sollte er das Probleme zuerst mit den bekannten Mitteln lösen.
  Mit Zitat antworten Zitat