Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 10.01.13 21:25 
Hi,

Ich habe folgendes Problem:

Ich möchte verschieden Datentypen in einer Datei speichern.
Bevor jetzt aber Vorshläge zum Thema "Records" kommen: Das nützt mir nichts.

Nehmen wir mal folgende Typen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
type
  TData=record
    Foo : integer;
    Bar : integer;
  end;

type
  TDataMap = array of array of TData;

type
  TDataFile = file of TData;


type
  TDataClas=class(TObject)
  private
    FData : TDataMap;
    FMapSize : TPoint;
    FMapName : string;
  public
    procedure LoadFromFile(filename:string);
    procedure SaveToFile(filename:string);
  end;

Ich könnte nun ein TDataFile abspeihern und tricksen indem ich die Grösse des Arrays in einem "Header record" packe und zuerst abspeichere. Die Datei hätte dann einen Record mehr als DataMap Elemente hat, aber das würde funktionieren. Aber wie kann ich nun den Daten und den Namen in einer Datei abspeichern?
In diesem Fall kann ich kein Datenfeld als Header missbrauchen (Foo und Bar sind beides Integer). Nur wegen dem Namen ein Datenfeld hinzuzufügen ist "schlecht" weil ich den Namen ja nur einmal pro Datei habe und nicht für jedes Datenfeld. Ich kann auch keinen Record definieren der Daten und den Namen enthält und dann einen Record abspeichern, da TDataMap keine feste Länge hat und daher tabu ist.

Wie speichert man gemischte Daten :?:

Wäre Dankbar für etwas Aufklärung :roll:

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Do 10.01.13 21:45 
So ganz hab ich Dein Problem nicht verstanden. Hier eine Möglichkeit:
ausblenden Quelltext
1:
2:
3:
4:
5:
Datentyp (Konstante Länge, z.B. 1 Byte)
Länge Beschreibung (Konstante Länge, z.B. 2 Bytes)
Beschreibung (variable Länge)
Länge der Daten (Konstante Länge, z.B. 4 Bytes)
Daten (variable Länge)

Je nach Datentyp kannst Du den Aufbau der Folgedaten anders gestalten. Prüfsummen zum Schützen vor Manipulation sind auch denkbar.

Gruß
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 10.01.13 22:31 
user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:
So ganz hab ich Dein Problem nicht verstanden. Hier eine Möglichkeit:
ausblenden Quelltext
1:
2:
3:
4:
5:
Datentyp (Konstante Länge, z.B. 1 Byte)
Länge Beschreibung (Konstante Länge, z.B. 2 Bytes)
Beschreibung (variable Länge)
Länge der Daten (Konstante Länge, z.B. 4 Bytes)
Daten (variable Länge)

Je nach Datentyp kannst Du den Aufbau der Folgedaten anders gestalten. Prüfsummen zum Schützen vor Manipulation sind auch denkbar.

Gruß


Hi,

Hmm, ich hab deine Antwort nicht verstanden.
Wie würde das denn praktisch aussehen wenn ich einen String einen Integer und ein dynamisches array von records speichern will?

Sähe die Datei dann so aus?
(Je ein Byte pro Zeile)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
42        // 42 steht für den typ "string"
6         // Wenn der String z.B. 'Delphi' lautet 
D         // Die Daten des Strings
e
l
p
h
i

Was meinst du mit "Beschreibung"?

Das läuft also darauf hinaus eine Datei byteweise zusammen und auseinander zu pfriemeln und Datentyoen wie integer, extended und andere mehrbyte Typen aus einzelnen gelesenen Bytes schneidern?
Oder hab ich da was falsch verstanden?

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Do 10.01.13 22:46 
catweasel hat folgendes geschrieben:
Sähe die Datei dann so aus?

Im Grunde ja. Mit Datentyp meinte ich jedoch den Aufbau, der Folgedaten. Sorry, hab mich da etwas ungünstig ausgedrückt.

catweasel hat folgendes geschrieben:

Wie würde das denn praktisch aussehen wenn ich einen String einen Integer und ein dynamisches array von records speichern will?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
Var w:Word;
    S:String;
    i:Integer;
    LengthDynArray:Cardinal;
...
Stream.Read(w,Sizeof(Word); //Gibt länge des Strings zurück
Stream.Read(S,w);
ShowMessage(S); //String anzeigen

Stream.Read(i,4); //32 Bit Integer

ShowMessage(IntToStr(i)); //Integer anzeigen

Stream.Read(LengthDynArray,4);
Stream.Read(DynArray,LengthDynArray);


Nur vom Prinzip her.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 10.01.13 22:48 
Wobei ich einfach eine Klasse nehmen würde, dieser die Methoden LoadFromStream und SaveToStream, dazu noch eine Klasse für die gesamte Datei, ebenfalls mit diesen Methoden und dazu LoadFromFile und SaveToFile. Dann ist das alles wunderbar gekapselt. Ein Beispiel müsste ich mal schreiben...
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Do 10.01.13 23:01 
Hallo,

was spricht eigentlich gegen eine XML Datei?

Grüße
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 10.01.13 23:09 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wobei ich einfach eine Klasse nehmen würde, dieser die Methoden LoadFromStream und SaveToStream, dazu noch eine Klasse für die gesamte Datei, ebenfalls mit diesen Methoden und dazu LoadFromFile und SaveToFile. Dann ist das alles wunderbar gekapselt. Ein Beispiel müsste ich mal schreiben...


Hab ich doch vor.
Guck mal die TDataClass Definition am Threadanfang an :)

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 10.01.13 23:17 
user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:
catweasel hat folgendes geschrieben:
Sähe die Datei dann so aus?

Im Grunde ja. Mit Datentyp meinte ich jedoch den Aufbau, der Folgedaten. Sorry, hab mich da etwas ungünstig ausgedrückt.

catweasel hat folgendes geschrieben:

Wie würde das denn praktisch aussehen wenn ich einen String einen Integer und ein dynamisches array von records speichern will?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
Var w:Word;
    S:String;
    i:Integer;
    LengthDynArray:Cardinal;
...
Stream.Read(w,Sizeof(Word); //Gibt länge des Strings zurück
Stream.Read(S,w);
ShowMessage(S); //String anzeigen

Stream.Read(i,4); //32 Bit Integer

ShowMessage(IntToStr(i)); //Integer anzeigen

Stream.Read(LengthDynArray,4);
Stream.Read(DynArray,LengthDynArray);


Nur vom Prinzip her.


Ah ok. Mit FileStreams hatte ich bisher kaum gearbeitet. Immer nur mit typisierten Dateien (im rudimentärsten Fall vom Typ Byte). Eine Frage habe ich aber noch zu:
ausblenden Delphi-Quelltext
1:
2:
Stream.Read(LengthDynArray,4);
Stream.Read(DynArray,LengthDynArray);

Erst wird die Länge als 4 Byte Cardinal eingelesen. Das check ich noch
Aber muss ich da nicht dann noch ein Setlength(DynArray,LengthDynArray); einfügen bevor ich die Daten lese?

Ich werde mich auf jeden Fall mal mit Streams auseinandersetzen.
Danke für den Tip :)

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Fr 11.01.13 01:07 
Hallo,


user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:

Ich werde mich auf jeden Fall mal mit Streams auseinandersetzen.


dann darf ich dir das gute Tutorial von user profile iconBenBE empfehlen:

Wie man Strings speichert und liest ...

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
rushifell
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Fr 11.01.13 18:57 
Für XML gibts doch bestimmt gute Libraries!?

catweasel hat folgendes geschrieben:
Aber muss ich da nicht dann noch ein Setlength(DynArray,LengthDynArray); einfügen bevor ich die Daten lese?


Ich nutze immer einen Buffer mit konstanter Größe, lese vom Stream in den Buffer und übergebe dann die Daten an das Dynamische Array. Sollte wahrscheinlich auch direkt gehen, hatte aber damit schon öfter Probleme.

Bei den Arrays musst Du unbedingt auf den Typ achten:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Var ByteArray:Array[1..2of Byte;
    IntegerArray:Array[1..2of Integer;
begin
ShowMessage(InttoStr(SizeOf(ByteArray)));    //2*1 Byte, also 2 Bytes lesen/schreiben
ShowMessage(InttoStr(SizeOf(IntegerArray))); //2*4 Bytes, also 8 Bytes lesen/schreiben
end;


Beim Schreiben und Lesen von Strings solltest Du Dir Gedanken machen, ob Du Unicode unterstützen möchtest (würde ich generell empfehlen).

Ich nutze übrigens gerne die TFastFileStream-Klasse von Flamefire:
www.entwickler-ecke....ewtopic.php?t=100088

Gruß
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 11.01.13 21:25 
Mit einer MMF wie sie auch in der Klasse verwendet wird kann man auch direkt als Array auf die Daten zugreifen. Da Windows diese automatisch in den RAM spiegelt, geht das extrem schnell.

Das Prinzip siehst du in dieser Unit von mir sehr gut, bei der das ganze Stream drum herum noch nicht drin ist. Deshalb ist die zum Verständnis vermutlich besser.
www.entwickler-ecke....ewtopic.php?p=607865

Für diesen Beitrag haben gedankt: rushifell
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Sa 12.01.13 12:36 
user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:

Ich nutze immer einen Buffer mit konstanter Größe, lese vom Stream in den Buffer und übergebe dann die Daten an das Dynamische Array. Sollte wahrscheinlich auch direkt gehen, hatte aber damit schon öfter Probleme.

Gruß


Hi,

Das mit den FileStreams hab ich das jetzt geblickt :)
Aber ein Problem hab ich noch:

Ich habe eine Klasse (TBaseClass) geschrieben welche zwei Felder einführt: "Name" und "Description" (beides Strings).
Davon abgeleitet ist TChildClassA, welche zwei zusätzliche Felder "Index" (Int64) und "Color" (TColor) einführt.

Die TBaseClass.LoadFromFile bzw. SaveToFile funktioniert ganz gut wenn ich den FileStream nach dem Lesen/Schreiben in der Prozedur wieder freigebe. (Ansonsten bleibt die Datei ja "in Verwendung").

Jetzt möchte ich TChildClassA auch LoadFromFile/SaveToFile Prozeduren geben. Dazu möchte ich aber die "Lese/Schreib-arbeit" für die Felder von TBaseClass nicht duplizieren.
Ich hatte mir gedacht ich ruf einfach die Parent Prozedur über inherited auf, speichere die zusätzlichen Felder hintendrann. Ob nun TBaseClass oder TChildClassA den "Sack zu" machen muss wollte ich per: if self is TChildClassA then FDiskFile.Free; testen.
Ich bekomme aber nur Fehler. Keine AccessViolation, sondern eine "External Exception". :shock: Einzelschritt debugging deutet an das das Freigeben des Streams irgendwie scheitert. Aber nur in TChildClassA....

Ich hab mal das Projekt hier eigefügt.
Wenn man das FDiskFile.Free in TBaseClass nicht auskommentiert, dann funktionierts damit. TBaseClass Objekte lassen sich dann lesen und speichern.

Wo liegt der Fehler :?:

Cheers,
Catweasel
Einloggen, um Attachments anzusehen!
_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Sa 12.01.13 13:51 
In der VCL gibt es (fast) immer eine SaveToFile Methode und eine SaveToStream Methode.
Mache es doch genau so: Die SaveToFile öffnet einen Filestream, ruft die andere Methode auf und schließt diesen wieder.
Die SaveToStream Methode kannst du dann überschreiben und die alte mit inherited aufrufen ;-)
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Sa 12.01.13 13:57 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
In der VCL gibt es (fast) immer eine SaveToFile Methode und eine SaveToStream Methode.
Mache es doch genau so: Die SaveToFile öffnet einen Filestream, ruft die andere Methode auf und schließt diesen wieder.
Die SaveToStream Methode kannst du dann überschreiben und die alte mit inherited aufrufen ;-)


Hmmm....Exakt das habe ich versucht und genau das Schliessen klappt nicht.
Wo liegt der Fehler in meinem Quelltext?

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Sa 12.01.13 14:24 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:

Hmmm....Exakt das habe ich versucht und genau das Schliessen klappt nicht.
Wo liegt der Fehler in meinem Quelltext?


Du machst es eben nicht exakt wie ich es vorgeschlagen hatte ;-) (SaveToStream <> SaveToFile)

Ich finde da nur:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TBaseClass.SaveToFile(filename: string);
var
Len : integer;
begin
FDiskFile := TFileStream.Create(filename,fmCreate);
Len := Length(FName);
FDiskFile.Write(Len,SizeOf(Len));
FDiskFile.Write(PChar(FName)^,Len);
Len := Length(FDescription);
FDiskFile.Write(Len,SizeOf(Len));
FDiskFile.Write(PChar(FDescription)^,Len);
if self is TBaseClass then FDiskFile.Free;
//FDiskFile.Free;
end;


Ich habe das hier gemeint:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TBaseClass.SaveToStream(AStream: TStream); // Natürlich virtual damit man überschreiben kann
var
Len : integer;
begin
Len := Length(FName);
AStream.Write(Len,SizeOf(Len));
AStream.Write(PChar(FName)^,Len);
Len := Length(FDescription);
AStream.Write(Len,SizeOf(Len));
AStream.Write(PChar(FDescription)^,Len);
end;

procedure TBaseClass.SaveToFile(filename: string);
begin
FDiskFile := TFileStream.Create(filename,fmCreate);
SaveToStream(FDiskFile);
FDiskFile.Free;
end;

Die SaveToStream-Methode kannst du dann in der Kind-Klasse überschrieben und aufrufen.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Sa 12.01.13 14:44 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:

Hmmm....Exakt das habe ich versucht und genau das Schliessen klappt nicht.
Wo liegt der Fehler in meinem Quelltext?


Du machst es eben nicht exakt wie ich es vorgeschlagen hatte ;-) (SaveToStream <> SaveToFile)

Ich finde da nur:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TBaseClass.SaveToFile(filename: string);
var
Len : integer;
begin
FDiskFile := TFileStream.Create(filename,fmCreate);
Len := Length(FName);
FDiskFile.Write(Len,SizeOf(Len));
FDiskFile.Write(PChar(FName)^,Len);
Len := Length(FDescription);
FDiskFile.Write(Len,SizeOf(Len));
FDiskFile.Write(PChar(FDescription)^,Len);
if self is TBaseClass then FDiskFile.Free;
//FDiskFile.Free;
end;


Ich habe das hier gemeint:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TBaseClass.SaveToStream(AStream: TStream); // Natürlich virtual damit man überschreiben kann
var
Len : integer;
begin
Len := Length(FName);
AStream.Write(Len,SizeOf(Len));
AStream.Write(PChar(FName)^,Len);
Len := Length(FDescription);
AStream.Write(Len,SizeOf(Len));
AStream.Write(PChar(FDescription)^,Len);
end;

procedure TBaseClass.SaveToFile(filename: string);
begin
FDiskFile := TFileStream.Create(filename,fmCreate);
SaveToStream(FDiskFile);
FDiskFile.Free;
end;

Die SaveToStream-Methode kannst du dann in der Kind-Klasse überschrieben und aufrufen.



Ah Ok :)
Ich werd das heute Abend mal testen.
Hab ich das richtig verstanden: Die SaveToFile Prozedur ist nur in der BAsisKlasse implementiert und die jeweilige KindKlasse ruft als erstes inherited SaveToStream(AStream) auf?
Warum muss AStream hier nicht als var Parameter übergeben werden?
So etwa: procedure TBaseClass.SaveToStream(var AStream:TStream);

Und dann könnte FDiskFile in der SaveToFile Prozedur auch eine lokale Variable sein. Dann brauche ich gar kein FileStream als Klassenfeld?
Mit dem Überschreiben von Prozeduren hab ich noch nicht so viel Erfahrung (mach ich sonst kaum).
Danke für die Tips :)

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Sa 12.01.13 14:48 
Objektinstanzen muss man i.d.R. nicht als Var-Parameter übergeben, da es sich intern um Pointer handelt. Und in den allermeisten Fällen möchte man ja nicht die Instanz an sich ändern, sondern deren Properties.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 13.01.13 14:07 
Hi,

vielen Dank an Alle die mit ihren tollen Tips geholfen haben. Echt Super :)
Schaut euch aber nch mal den Sourcecode an und sagt mir ob es da noch formal etwas zu verbessern gibt.
Irgendein Feld oder eine Methode die öffentlicher ist als nötig?

Cheers,
Catweasel
Einloggen, um Attachments anzusehen!
_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 13.01.13 19:07 
Hallo

würde das ganze noch um die TWriter und TReader ergänzen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TBaseClass.SaveToStream(AStream: TStream); // Natürlich virtual damit man überschreiben kann
Var Writer:Twriter;
  begin
    writer:= Twriter.create(AStream,4096);
    try
      begin
        //version schreiben
        writer.writeInteger(aktuelleVersionsNummer);
        writer.writeString(...);
        writer.writeBoolean(...);
        writer.writefloat(...);
        writer.writeDate(...);       
      end;
    finally
      writer.free;
    end;
end;

auslesen mit Treader genau andersrum.
Brauchst halt nicht für jeden Datentyp dir extra was einfallen lassen, das ist schon da.
Außerdem ließt es sich meiner Meinung nach besser, da es alles Einzeiler sind. Es wird wahrscheinlich auch zukunftssicherer sein, grade, wenn Du strings schreibst.

Gruß Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 13.01.13 19:36 
user profile iconKeldorn hat folgendes geschrieben Zum zitierten Posting springen:
Hallo

würde das ganze noch um die TWriter und TReader ergänzen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TBaseClass.SaveToStream(AStream: TStream); // Natürlich virtual damit man überschreiben kann
Var Writer:Twriter;
  begin
    writer:= Twriter.create(AStream,4096);
    try
      begin
        //version schreiben
        writer.writeInteger(aktuelleVersionsNummer);
        writer.writeString(...);
        writer.writeBoolean(...);
        writer.writefloat(...);
        writer.writeDate(...);       
      end;
    finally
      writer.free;
    end;
end;

auslesen mit Treader genau andersrum.
Brauchst halt nicht für jeden Datentyp dir extra was einfallen lassen, das ist schon da.
Außerdem ließt es sich meiner Meinung nach besser, da es alles Einzeiler sind. Es wird wahrscheinlich auch zukunftssicherer sein, grade, wenn Du strings schreibst.

Gruß Frank


Wow. TReader/TWriter kannte ich auch noch nicht. Ich hab da mal ne Frage zu. Als ich auf der Embacaero Website mir ein paar Sachen dazu durchgelesen habe: docwiki.embarcadero....stem.Classes.TWriter bin ich etwas verwirrt. Dort steht das man TReader/TWriter nicht direkt erzeugen soll weil das sowieso schon Bestandteil der TSTream Klasse ist.

Hab ich das was falsch verstanden? Ich finde uach kaum "Tutorials" zu TREader/TWriter...
Und was ist die Obergrenze für die Buffergröße?. Hab dazu auch nichts gefunden.

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.