Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Stringgrösse in einem Record ändern (https://www.delphipraxis.net/215915-stringgroesse-einem-record-aendern.html)

oldmann 24. Sep 2024 18:45

Stringgrösse in einem Record ändern
 
Hallo,
Ich habe in einem Record unter anderen einem String, Energieart:string[10]:
type
energie=Record
monat:String[15];
Energieart:string[10];
usw-----
usw-----
end;
Nun müsste ich den String 'Energieart' von string[10] auf von string[15] erweitern.
Das Programm läuft aber schon einige Jahre mit string[10].
Wie kann den record auf string[15] ändern, ohne dass die Dateien die bisher Erstellt wurden Probleme haben.
Vielleicht gibt es ja dafür eine Lösung.
Gruss oldmann

Andreas13 24. Sep 2024 20:10

AW: Stringgrösse in einem Record ändern
 
Vermutlich bleibt Dir nichts anderes übrig, als die "alten" Daten einzulesen und im neuen Format umzuspeichern. :wink:

Uwe Raabe 24. Sep 2024 20:56

AW: Stringgrösse in einem Record ändern
 
Deklariere zwei Versionen des Records.
Delphi-Quellcode:
type
  energieV1 = Record
    monat: String[15];
    Energieart: string[10];
  // ...
  end;

  energieV2 = Record
    monat: String[15];
    Energieart: string[15];
  // ...
  public
    class operator Implicit(A: energieV1): energieV2; overload;
  end;

  energie = energieV2;

...

class operator energieV2.Implicit(A: energieV1): energieV2;
begin
  Result.monat := A.monat;
  Result.Energieart := A.Energieart;
  // ...
end;
Beim Lesen und Schreiben neuer Dateien verwendest du energieV2, beim Lesen alter Dateien energieV1. Das Schreiben des alten Formats solltest du vermeiden, da es zu Datenverlust führen kann. Wie du eine Datei im alten Format erkennen kannst, musst du selbst entscheiden (z.B. andere Extension oder eine definierte Signatur, die nicht mit dem V1-Record kollidiert).

Mit dem implicit operator kannst du einen V1-Record einfach einem V2-Record zuweisen.
Delphi-Quellcode:
procedure Lies(out Rec: energie1); overload; ...
procedure Lies(out Rec: energie2); overload; ...

procedure LiesRecord(out Rec: energie);
var
  RecV1: energieV1;
begin
  if IsFormatV1 then begin
    Lies(RecV1);
    Rec := RecV1;
  end
  else
    Lies(Rec);
end;
Die Typen mit den Versionsnummern würde ich beibehalten, da vermutlich irgendwann wieder eine Erweiterung ansteht.

Um den Code kompatibel zu halten, habe ich den Alias eingeführt. Bei den Lese-/Schreib-Methoden solltest du die versionierten Typnamen verwenden. Dann können die beim Versionswechsel so bleiben.

jaenicke 25. Sep 2024 05:29

AW: Stringgrösse in einem Record ändern
 
Wobei sich auch die Frage stellt, ob es bei dieser Art der Speicherung bleiben soll. Klar, es ist einfach zu verwenden, aber bei der nächsten Anpassung stehst du wieder an der gleichen Stelle.

Alternativen gibt es viele (z.B. JSON). Aber natürlich ist der Aufwand für eine Umstellung größer. Inkompatibel mit dem vorherigen Format ist das neue Format aber in jedem Fall, auch wenn es nur ein neuer Record wird, wie Uwe ausführlich gezeigt hat. Da also ohnehin zwischen den Dateiversionen unterschieden werden muss, könnte man auch ganz etwas anderes verwenden.

dummzeuch 25. Sep 2024 08:53

AW: Stringgrösse in einem Record ändern
 
Das Problem bei Uwes Vorschlag ist, wie er selbst schon schreibt, dass man beim Lesen einer Datei wissen muss, welcher Record-Typ in die Datei geschrieben wurde. Das kann schnell mal in die Hose gehen.

Wir verwenden deshalb intern ein selbstbeschreibenden File of Record Format, basierend auf dem Code aus "Tomes of Delphi". Darin wird in einem Header u.a. der Name und eine Feldbeschreibung des gespeicherten Records geschrieben. Das hat noch den Vorteil, dass wir dafür einen generischen Viewer bauen konnten.

Zusätzlich haben wir noch eine Prüfsumme und Metadaten für die ganze Datei eingebaut.

Blup 26. Sep 2024 12:54

AW: Stringgrösse in einem Record ändern
 
Wenn man unbedingt abwärts kompatibel bleiben muss.
Für Energieart nur eine Kürzel speichern und die Übersetzung Kürzel zu Langbezeichnung in einer zusätzlichen Datei.
Den neuen Record vor dem Speichern in den alten Record kopieren und dabei die Langbezeichnung durch das Kürzel ersetzen.
Beim Lesen entsprechend umgekehrt.

oldmann 26. Sep 2024 16:21

AW: Stringgrösse in einem Record ändern
 
Hallo,
erst einmal Danke für Eure Antworten.
Die meisten waren mir schon beknnt, aber ich dachte vielleicht gibt es eine ganz einfache Lösung.
Es wird mir wohl nichts anderes Übrig bleiben, als die Daten im alten Record auszulesen und in einem neue Record zu speichern.
Also nochmal danke.
Oldmann

himitsu 26. Sep 2024 16:58

AW: Stringgrösse in einem Record ändern
 
oder besser gleich in was Anderem speichern, welches sich zukünftig problemloser ändern lässt.

oldmann 28. Sep 2024 13:03

AW: Stringgrösse in einem Record ändern
 
Hi himitsu,
Was gibt es da für Möglichkeiten?
Was wäre die beste Möglichkeit?
Eventuel Bespiele ?
Gruss Okdmann

jaenicke 28. Sep 2024 13:43

AW: Stringgrösse in einem Record ändern
 
JSON habe ich ja schon genannt. Möglich wäre auch XML, das für Menschen besser lesbar ist.

Grundsätzlich kannst du dann entweder das Speichern und Einlesen z.B. mit superobject manuell machen oder ein Marshalling verwenden, wie hier gezeigt wird:
https://github.com/pult/SuperObject....in-delphi-2010

dummzeuch 28. Sep 2024 13:51

AW: Stringgrösse in einem Record ändern
 
Jemandem als Alternative zu einem File of Record JSON oder XML zu empfehlen, ist mutig. Die Performance geht dann deutlich in den Keller, wenn es um mehr als eine Handvoll Records geht.

jaenicke 28. Sep 2024 14:17

AW: Stringgrösse in einem Record ändern
 
Das stimmt natürlich.

Uwe Raabe 28. Sep 2024 15:09

AW: Stringgrösse in einem Record ändern
 
Ich bin mir auch nicht sicher ob human readable überhaupt wünschenswert oder gar notwendig ist. Das bedeutet nämlich immer auch human writable und erschwert die Plausibilitätskontrolle beim Einlesen beträchtlich.

Delphi.Narium 28. Sep 2024 15:25

AW: Stringgrösse in einem Record ändern
 
Wie wäre es mit 'ner Memorytable? Da kann man nachträglich die Größe von Stringfeldern problemlos nach oben (ohne Datenverlust) verändern. Man kann sie als Datei speichern und natürlich auch wieder einlesen und als "Schmakerl" obendrein wie 'ne Datenbanktabelle ansprechen.

Zitat:

Zitat von Uwe Raabe (Beitrag 1541605)
Ich bin mir auch nicht sicher ob human readable überhaupt wünschenswert oder gar notwendig ist. Das bedeutet nämlich immer auch human writable und erschwert die Plausibilitätskontrolle beim Einlesen beträchtlich.

Da kann man ja dann 'ne verschlüsselte Datenbank nehmen. Oder die XML, JSon, ... in 'ner verschlüsselten ZIP speichern, ...

Und wenn bisher ein Record gespeichert wurde, ist das sicherlich human readable, man muss ggfls. nur einmal die einzelnen Werte im Record analysieren. Damit kann man dann auch recht problemlos DBase-Dateien (o. ä.) lesen. Header + feste Satzlänge. Bei Records halt "nur" feste Satzlänge.

dummzeuch 28. Sep 2024 15:45

AW: Stringgrösse in einem Record ändern
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1541606)
Und wenn bisher ein Record gespeichert wurde, ist das sicherlich human readable, man muss ggfls. nur einmal die einzelnen Werte im Record analysieren. Damit kann man dann auch recht problemlos DBase-Dateien (o. ä.) lesen. Header + feste Satzlänge. Bei Records halt "nur" feste Satzlänge.

Die wenigsten trauen sich, binäre Dateiformate zu editieren. Aber bei Textdateien ist die Hemmschwelle deutlich geringer und vor allem sehen sie darin auch kein Problem, denn es ist ja Text.

Delphi.Narium 28. Sep 2024 15:57

AW: Stringgrösse in einem Record ändern
 
Naja, wenn ich mir so manche JSon anschaue, dann traue ich mich da aber auch nicht mit dem Editor dran. Man kann sie quasi deutlich lesbar uneditierbar machen. Einfach mal nur 50 MB als Einzeiler ;-) Bei XML kann es sehr ähnlich zugehen. Oder wenn man sich so manche HTML-Seite ansieht, was die Browser da leisten müssen, um was lesbares daraus zu erstellen, das ist schon heftig.

Da erscheinen mir Dateien, in denen einfach Records mit fester Länge hintereinandergeschrieben werden, schon beinahe als deutlich einfacher zu manipulieren ;-)

Und nein, wirklich sicher geht nicht, die Frage ist nur, mit welchem Aufwand kann man an die Daten ran und lohnt der Aufwand dann noch.

Da wir nicht wissen was für Daten hier konkret gespeichert werden und wie "sicher" sie sein müssen, kann es durchaus unkritisch wein, wenn die Daten nicht manipulationssicher sind.

dummzeuch 28. Sep 2024 16:48

AW: Stringgrösse in einem Record ändern
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1541608)
Naja, wenn ich mir so manche JSon anschaue, dann traue ich mich da aber auch nicht mit dem Editor dran.

Du schon, aber Du weißt, dass JSON nicht zum Editieren durch User gedacht ist und welche Folgen es haben kann, wenn man das Format kaputt macht. Der typische User weiß das nicht.

Zitat:

Zitat von Delphi.Narium (Beitrag 1541608)
Da erscheinen mir Dateien, in denen einfach Records mit fester Länge hintereinandergeschrieben werden, schon beinahe als deutlich einfacher zu manipulieren ;-)

Und nein, wirklich sicher geht nicht, die Frage ist nur, mit welchem Aufwand kann man an die Daten ran und lohnt der Aufwand dann noch.

Da wir nicht wissen was für Daten hier konkret gespeichert werden und wie "sicher" sie sein müssen, kann es durchaus unkritisch wein, wenn die Daten nicht manipulationssicher sind.

Mir ging es dabei weniger um "manipulationssicher" sondern um (nicht nachvollziehbare) Programmfehler, die dadurch entstehen, dass User scheinbar "einfache" Textdateien verändern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 Uhr.

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