Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Binärdatei auslesen - gespeichertes Objekt ist geändert (https://www.delphipraxis.net/124998-binaerdatei-auslesen-gespeichertes-objekt-ist-geaendert.html)

Flippo 28. Nov 2008 17:29


Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Hallo zusammen,
ich habe folgendes Problem:
Das Programm speichert eine Collection Namens Elementlisten die aus Elementen vom Typ TMyElement besteht in eine Binärdatei. Die Collection wird dann später wieder aus dieser Binärdatei erzeugt. (Dabei wird der Kontruktur für jedes Einzelne Element automatisch aufgerufen). Der Konstruktur liest dann die benötigten Daten mit Hilfe der read Prozedur ein. (Am besten an dieser Stelle mal einen Blick in den Quelltext werfen, damit ihr versteht was ich zu sagen versuche :stupid: )
Das Problem ist jetzt: Das Attribut Stand(ein String) hat eine neue Länge bekommen(wurde von 3 auf 5 geändert). Ich weiß leider nicht genau wie das Suchen in der Binärdatei abläuft, aber ich schätze mal er sucht nach etwas der Art "Stand: String[5]"(natürlich wird das in der Binärdatei durch wirre zeichen dargestellt). Ist die Binärdatei alt, dann steht da aber noch "Stand: String[3]" drin. Weshalb der Stand dann nicht gefunden wird, wohl bis ans ende des Streams gelaufen wird und beim ersten Zugriffsversuch auf irgendein Element der Collection eine "Schutzverletzung" kommt.
(Wenn ich Daten die von der aktuellen Version gespeichert wurden öffne gibt es keine Fehler)

Deshalb meine Fragen:
Gibt es eine Möglichkeit im Konstruktor den alten Stand auszulesen? Ich bekomme es einfach nicht hin, obwohl ich ja folgendes problemlos augelesen bekomme
Neu: TMyElementliste hat Attribut "Stand: TStandStr" (an anderer Stelle wird TStandStr: String[5] definiert). Und die einzige Änderung bekannt ist
Alt: TMyElementliste hat Attribut "Stand: TStandStr" (TStandStr hat länge 3)

Wie oder woher kann ich Informationen darüber bekommen wie diese Binärdateien aufgebaut sind? Das wurde ja alles mit Hilfe von standard Methoden da reingeschrieben.

Delphi-Quellcode:
procedure Binaerlisten_schreiben (fn : PChar);
var
  TheFile: TBufStream;
begin
  TheFile.Init(fn, stCreate, 1024);
  TheFile.Put(Elementlisten);
  TheFile.Done;
end;

{Die obere Prozedur löst wohl diese hier zum schreiben für jedes Element aus}
procedure TMyElement.Store(var s : TStream);
begin
  Application.ProcessMessages;
  S.Write(Name, SizeOf(ElementName));
  S.Write(Bereich, SizeOf(Bereich));
  S.Write(data, SizeOf(data));
  S.Write(Dateiname, SizeOf(DateiName));
  S.Write(Stand, SizeOf(Stand));
  S.Write(Numm, SizeOf(INumm));
  S.Write(Datum, SizeOf(Datum));
end;


{Hier der Kontruktor der vom einlesen Befehl aufgerufen wird}
constructor TMyElement.Load (var s : TStream);
begin
  { auf Default-Werte setzen }
  FillChar (data, sizeof(data), #0);
  isNewList := false;
  bereichIndex := 0; { wird dann im Bereiche-Setup neu gesetzt }
  s.Read(Name, sizeOf(Name));
  s.Read(bereich, sizeOf(Bereich));
  s.Read(data, sizeOf(data));
  s.Read(Dateiname, sizeOf(DateiName));
  s.Read(Stand, sizeOf(Stand)); {Hier ist das Problem}
  s.Read(Numm, sizeOf(INumm));
  s.Read(Datum, sizeOf(Datum));
end;
Ich hoffe Ihr könnt mir helfen. Danke schonmal an alle die sich hiermit befassen.

MfG

flippo

nicodex 28. Nov 2008 17:56

Re: Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Sieht nach einem klassischen (Daten-)Kompatibilitätsproblem aus.
Um dein aktuelles Problem zu lösen würde ich (für die Zukunft) eine Signatur und eine (Daten-)Versionsinformation an den Anfang der Datei schreiben. Ist der Header (bzw. die Signatur) nicht vorhanden, dann handelt es sich um das ganz alte Format.
Damit nicht tausend Versionsabfragen in deinem Code stehen, solltest du die Länge der Datensätze mit in die Binärdaten schreiben (mindestens für die Strings). Man kann das ganze derart abstrahieren, dass jede Eigenschaft einen eigenen Header mit Größe und Typ enthält (Chunks).
Kurz, du solltest dir überlegen, welche Erweiterungen des Formats noch kommen könnten - und dementsprechend ein Datenformat entwerfen.

Flippo 28. Nov 2008 21:27

Re: Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Hi,
das unterscheiden der Formate ist nicht das Problem. Mir ist bekannt welches Format wann vorliegt und wie sie aufgebaut sind. Nur wie oben beschrieben bekomme ich es trotzdem nicht hin die alten Daten auszulesen. Ich beschäftige mich zum ersten mal mit Binär-Dateien. Deshalb nochmal, was für Möglichkeiten gibt es so gespeicherte Objekte auszulesen?
Und kann man wenigstens aus den Binärdateien halbwegs sinnvoll weiterzuverabreitende Daten bekommen?

Deine Anregungen zum Datenformat sind sicherlich sinnvoll. Allerdings ist das Programm eine uraltes Flickwerk, das ich nicht selbst verbrochen habe. Ich müsste so ziemlich alles Umschreiben, was sich nicht lohnen würde, da keine weiteren Änderungen am Datenformat geplant sind und eine komplette Neuentwicklung das Programms bereits in Arbeit ist).
Leider darf ich nicht einfach auf die neue Version warten, also wäre ich echt dankbar wenn ihr mir ein paar Tips geben könntet (Komplettlösungen würde ich natürlich auch nehmen :zwinker:).

Flippo 1. Dez 2008 08:36

Re: Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Kann mir wirklich keiner helfen? Ich habe komplett keine Ahnung was ich tun muss. :wall:
Ich bin hier echt am verzweifeln, mit dem .....!

Reinhard Kern 1. Dez 2008 09:07

Re: Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Zitat:

Zitat von Flippo
Kann mir wirklich keiner helfen? Ich habe komplett keine Ahnung was ich tun muss. :wall:
Ich bin hier echt am verzweifeln, mit dem .....!

Hallo,

es ist eher ein Wunder, wenn überhaupt noch was funktioniert - bei einer Binärdatei ist es wie bei einem Record (wahrscheinlich, ich kenne ja die Schreibsoftware nicht), alles kommt einfach nacheinander, und wenn sich die Länge eines Elements ändert, funktioniert i.d.R. auch der Zugriff auf alle folgenden nicht mehr.

Trotzdem verstehe ich das Problem nicht: wenn du weisst, es ist das alte Format, nimmst du das bisherige Programm, und für das neue Format musst du eine geänderte Version schreiben, die du verwendest, wenn die Datei im neuen Format vorliegt. Das geht immer - selbst wenn du von Binär auf SQL umstellst, kannst du ja das gesamte Einlesen neu schreiben. Das ist das Schicksal alter Software, ich stelle auch gerade von einer binären Datei (Pascal file of type) um auf XML, da ist natürlich die DB-Software komplett neu und es wird nach Dateityp die alte oder die neue verwendet.

Gruss Reinhard

Flippo 1. Dez 2008 10:19

Re: Binärdatei auslesen - gespeichertes Objekt ist geändert
 
Ja, das ich anders einlesen muss war mir schon klar. Ich bin nur (bis eben) nicht so richtig dahinter gekommen, wie das mit dem Aulesen einer solchen Datei mittels TBufReader funktioniert. Jetzt klappt aber zumindest dieser Teil. Für mich hat es jetzt schon ausgereicht, die Position mit getPos vor dem Auslesen der geänderten Zeile zu speichern und gegebenenfalls mit seek um 2 Stellen zurückzusetzen.

Danke euch trotzdem
MfG
Flippo


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz