![]() |
Strukturierte Daten in Datei speichern
Folgendes: Ich habe Daten in Form Überschrift und dazu einen Text und das immer abwechselnd. Dies wollte ich jetzt abspeichern.
Nur wie? Typisierte Datei mit Records ist schlecht, da man da ja nur ShortStrings verwenden kann, der Text kann aber leider größer werden als 255 Zeichen. Jetzt dachte ich, kuckst du dir doch mal TFileStream an. Gesagt, getan. Also ich weiß nicht ob es damit geht oder nicht. Und wenn es geht, dann wüßte ich nicht wie. Das Problem ist halt, dass die Textlänge sehr variable ist. Nachtrag: Ein nachträgliches Bearbeiten soll auch möglich sein. Irgendwelche Ideen, Vorschlage, Lösungen? |
Vielleicht hilft dir das bei TFileStream:
Delphi-Quellcode:
Damit kannst du Strings mit der theoretischen Länge von 4 GB schreiben und einlesen.
// schreibt 4 Bytes Stringlänge und danach S
procedure WriteStreamStr(Stream: TStream; const S: String); var len: Cardinal; begin len := Length(S); Stream.Write(len, SizeOf(len)); if len > 0 then Stream.Write(S[1], len); end; // liest was WriteStreamStr geschrieben hat procedure ReadStreamStr(Stream: TStream; var S: String); var len: Cardinal; begin Stream.Read(len, SizeOf(len)); SetLength(S, len); if len > 0 then Stream.Read(S[1], len); end; // liest was WriteStreamStr geschrieben hat function ReadStreamStr(Stream: TStream): String; begin ReadStreamStr(Stream, Result); end; |
Gut. Ich glaube, das habe ich verstanden.
Aber:
Code:
Woher weiß ich jetzt, wo was anfängt und aufhört?
Titel
TextTextTextTextTextTextTextTextTextText TextTextTextTextTextTextText TextTextTextTextTextTextTextTextText TextTextTextText Titel TextTextTextTextText TextTextText TextTextTextTextTextText Titel TextTextText TextTextTextText Titel TextTextTextTextText TextTextTextTextText TextTextText |
Ich dachte du hast die Daten bereits im Speicher, dann kannst du mit
Delphi-Quellcode:
procedure WriteEntry(Stream: TFileStream; const Entry: TEntry);
begin WriteStreamStr(Stream, Entry.Titel); WriteStreamStr(Stream, Entry.Lines.Text); end; function ReadEntry(Stream: TFileStream): TEntry; begin Result.Titel := ReadStreamStr(Stream); Result.Lines.Text := ReadStreamStr(Stream); end; |
Du musst irgendeine Art Trennzeichen einführen denn irgendeine Information darüber, wie die Daten gegliedert sind, brauchst du ja bei erneutem Einlesen. Also Trennzeichen oder Header-Block mit Byte-Anzahl.
|
Das mit dem Header würde mir am ehesten zusagen.
Wie könnte denn so ein Header aussehen? Der muß ja auch dynamisch sein. Wenn am Tect was geändert wird oder wenn was rausgelöscht wird usw. |
Du könntest eine Art "Speicherverwaltung" auf Dateibasis bauen.
Delphi-Quellcode:
Dadurch dass du den Header von den eigentlichen Daten trennst, kannst du den Titel und Text an einer völlig anderen Stelle in der Datei ablegen. Sollte also der Platz nicht mehr ausreichen, so verlegst du die Daten einfach an eine Stelle, an der genug Platz vorhanden ist, oder vergrößerst die Datei.
THeader = packed record
TitelLen: Integer; TextLen: Integer; TitelPos: Longword; // Dateiposition des Titels (bei 0: Freier Block) TextPos: Longword; // Dateiposition des Textes Next: Longword; // Dateiposition des nächsten Headers (bei 0: Letzter Block) end; |
Du musst eben irgendwie reinschreiben, wieviel Bytes der folgende Speicherblock enthält, oder, falls es nur-Text-Daten sind, auch die Zeilenanzahl. Also so zum Beispiel:
mit Zeilen:
Code:
oder eben mit der Byte-Länge:
5
Titel TextTextTextText Text Text TextTextText 2 Titel TextText 4 Titel TextTextText Text Text TextTextTextText
Code:
Hier müsstest du also die Zahl in der ersten Zeile einlesen, einen weiteren Zeilenumruch überspringen und dann die nächsten 54 Bytes (ist nur überschlagen, können im Beispiel auch 53 oder 55 sein) einlesen. Alternativ wären zwei Längenangaben, wenn du Titel und Text trennen willst.
54
Titel Das ist ein kurzer Text, der 49 Zeichen lang ist. |
Ich glaube Chewie und ich denken an unterschiedliche Intentionen deiner Seits Luckie. Dadurch das du von Typisierten Dateien sprachst, bin ich natürlich in Richtung Datenbank ausgeschert.
|
@jbg: Ist gar nicht so schlimm. Dadurch ergeben sich eventuell neue Möglichkeiten, wenn man das von zwei unterschiedlichen Seiten angeht. Aber lies dir noch mal durch, was ich genau in meinem ersten Posting geschrieben habe. Bisher gefällt mir deien Idee noch am besten. Die Idee von Chewie sieht mir mehr so nach einer basteln Lösung aus.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:51 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 by Thomas Breitkreuz