speichern/laden von Komponenten als Textdatei via Stream

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

speichern/laden von Komponenten als Textdatei via Stream

Beitrag von u-boot »

Das speichern und laden einer Komponente geht, bei 2 Komponenten bekomme ich allerdings die Fehlermeldung:
EParsererror with message: wrong token symbol: INLINE expected but K1 found.
[ Zusatzinfo: ] K1 ist Name der 2. Komponente vom Typ TKnoten
[ Zusatzinfo: ] TKnoten=class(TForm)

Füge ich manuell in die Datei das wort "inline" vor K1 ein funktioniert es auch die Datei zu laden.
Was bedeutet dieses Inline? Warum wird das Wort inline Erwartet ? ich find die Datei sieht ohne inline schöner aus aber wenns nötig ist...
Falls man dieses Inline an dieser Stelle unbedingt braucht, wie kann man das beim streamen der Datei einfügen lassen ?

Meine bisherige Speicherprozedur:

Code: Alles auswählen

procedure TGraphGround1.SaveGraph(const path: string);
var filestream:TFilestream;
    memstream:TMemoryStream;
    i:Integer;
begin
  filestream:=TFileStream.Create(path, fmCreate);
  memstream:=TMemoryStream.Create;
  try
    i:=0;
    while (i<ComponentCount) do begin
      if (Components[i] is TKnoten)  then begin
        memstream.WriteComponent(Components[i]);
      end;
      inc(i);
    end;
    memstream.Seek(0,soFromBeginning);
    while (memstream.Position<memstream.Size) do begin
      ObjectBinaryToText(memstream,filestream);
    end;
  finally
    memstream.Free;
    filestream.Free;
  end;
end;


Bisherige Prozedur zum laden:

Code: Alles auswählen

procedure TGraphGround1.LoadGraph(const path: string);
var filestream:TFileStream;
var memstream:TMemoryStream;
var knot:TKnoten;
begin
  filestream:=TFileStream.Create(path, fmOpenRead); memstream:=TMemoryStream.Create;
  try
    while (filestream.Position<filestream.Size) do begin
      memstream.Seek(0, soFromBeginning);
      ObjectTextToBinary(filestream,memstream);
      memstream.Seek(0, soFromBeginning);
      knot:=TKnoten.Create(self);
      memstream.ReadComponent(Knot);
    end;
  finally
    memstream.Free;  filestream.Free;
  end;
end;


Der erstellte Dateiinhalt:

Code: Alles auswählen

object K0: TKnoten
  Left = 41
  Height = 69
  Top = 170
  Width = 69
  BorderIcons = []
  BorderStyle = bsNone
  Caption = 'K0'
  FormStyle = fsStayOnTop
  ParentFont = True
  ShowInTaskBar = stNever
  LCLVersion = '0.9.28.2'
  Visible = True
  TabStop = False
  Shape = stEllipse
end
object K1: TKnoten
  Left = 82
  Height = 46
  Top = 108
  Width = 46
  BorderIcons = []
  BorderStyle = bsNone
  Caption = 'K1'
  FormStyle = fsStayOnTop
  ParentFont = True
  ShowInTaskBar = stNever
  LCLVersion = '0.9.28.2'
  Visible = True
  TabStop = False
  Shape = stEllipse
end
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

martin_frb
Beiträge: 572
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von martin_frb »

"inline" beeinflusst wem untergeordnete (child) Komponenten gehören.

Normalerweise gehören alle Komponenten, dem Top-Level (Root) Element. (Parent ist der jeweils direkt übergeordnete). Mit Inline können auch andere Komponenten als Owner genutzt werden.

Ich denke das ist nicht das wirkliche Problem.

Teste doch mal die Stream-Position nach dem ersten lesen. Vielleicht hat der ja zu weit gelesen ? Inline wird nämlich anstatt von object verwendet. Also
object inline K1
macht gar keinen Sinn (wenn ich mich richtig erinnere)

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von u-boot »

Dankeschön das hilft schon ein ganzes Stück weiter.
Mit der Streamposition hattest recht. die ist vor dem lesen der 2. Komponente zwischen "object" und "K1".

Somit macht für das Programm die Zeile
object inline K1
schon einen Sinn, weil er ja das object nicht mehr neu liest.

Die Position um die paar Buchstaben zu verändern ist nicht soo schwierig. Mich wundert das Verhalten aber doch, weil das "end" für mich bisher als eindeutiges Komponentenende gegolten hatte.
Mit mehr als 2 Komponenten bin ich mal gespannt, probier ich aber erst morgen.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

martin_frb
Beiträge: 572
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von martin_frb »

Meines erachten nach, ist das ein Bug, in ReadComponent => aber so genau kann ich das nicht sagen.

Normalerweise hat ein Stream nur einen Komponent, alle anderen sind im übergeordneten Komponent. Auf der anderen Seite spricht nix dagegen, mehrere Komponenten hintereinander zu speichern....

piper62
Beiträge: 131
Registriert: Sa 5. Apr 2008, 17:57
OS, Lazarus, FPC: Linux (Debian, Xubuntu), MacOS X, MS Win, Android, Web
CPU-Target: 32Bit/64Bit
Wohnort: Ulm

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von piper62 »

Ich hatte das mal mit Matthias beim letzten Jahrestreffen besprochen und die Aussage war, dass nur eine Komponente gelesen wird.
Die weiteren sollten dann an dieser hängen.

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von u-boot »

Ich habs mal versucht einen Patch zu schreiben.....die Herangehensweise war allerdings relativ naiv und bin mir sehr unsicher ob der Patch wirklich funktionieren kann. Wäre schön wenns jemand testen könnte.
http://bugs.freepascal.org/view.php?id=16257
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von u-boot »

mal nen kleines update ... der patch besteht genau genommen aus einem begin und einem end und dazwischen sind 2 Anweisungen die schon zuvor dastanden ..... meines Erachtens funktioniert er aber ( frei nach dem motto versuch macht kluch). Mal sehen, ob und wann irgendjemand drauf kommt den Patch auch in FPC einzubauen.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

u-boot
Beiträge: 306
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von u-boot »

Mal ne Frage zu dem Komponentenstreaming:
Ich habe festgestellt, dass es evtl wirklich komfortabler ist die Owner-Komponente zu speichern, obwohl das andere mit dem Patch soweit auch geht.
Meine UnterKomponenten hatten ursprünglich einen Owner aber keinen Parent. (Also Parent=nil )
Beim Laden der Owner-Komponente wird nun jedoch den Unterkomponenten ein Parent zugewiesen (Parent=Owner).
Ist das vom System her nun so gewollt oder ist das ein weiterer Bug ?
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

Bora4d
Beiträge: 290
Registriert: Mo 24. Dez 2007, 13:14
OS, Lazarus, FPC: WinXP-Pro-Sp3, Xubuntu 12.04, (Laz 1.1-SVN Mai2012, FPC 2.6.1 / 2.6.0-Linux)
CPU-Target: AMD64X2

Re: speichern/laden von Komponenten als Textdatei via Stream

Beitrag von Bora4d »

Ich habe eben gerade über Kompoentenstreaming gelesen als ich eine Lösung für mein Problem suchte vielleicht hilft dir das:
http://wiki.lazarus.freepascal.org/Streaming_components

Antworten