Hi habnefrage,
ich kann Pit nur zustimmen. Zusätzlich solltest Du etwas in die Zukunft blicken. Mit neuen Versionen Deines Programmes bekommen Deine Objekte wahrscheinlich weitere Eigenschaften, die Du natürlich auch abspeichern werden willst. Dann wirst Du Dein Dateiformat ändern müssen. Natürlich willst Du die alten Dateien nicht wegschmeißen müssen, sondern willst dass Deine neue Programmversion auch die alten Dateien einlesen kann. Mit typisierten Dateien wirst Du dann für jedes Format einen eigenen Code haben.
Ich habe Pits Beispiel hergenommen und so abgeändert, dass es total einfach ist den Schülern weitere Attribute zu verpassen. Ich setze dazu allerdings nicht direkt auf den Streamklassen der VCL auf, sondern auf eigenen Klassen, die aber jeder kostenlos von meiner
Homepage herunter laden kann.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212:
| unit Mainform;
interface
uses RakBinaryStreamData, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, contnrs;
type TSchuelerList = class;
TForm1 = class(TForm) BtnSave: TButton; BtnLoad: TButton; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BtnSaveClick(Sender: TObject); procedure BtnLoadClick(Sender: TObject); private FSchuelerliste: TSchuelerList; public end;
TSchueler = class(TObject) private FName: String; FVorname: String; FStufe: Integer; public procedure LoadFromBinaryTag(const Tag: TRakBinaryTag); procedure SaveToBinaryTag(const Tag: TRakBinaryTag);
property Name: String read FName write FName; property Vorname: String read FVorname write FVorname; property Stufe: Integer read FStufe write FStufe; end;
TSchuelerList = class(TObject) private FList: TObjectList; function GetCount: Integer; function GetSchueler(Index: Integer): TSchueler; public constructor Create; destructor Destroy; override; function AddSchueler: TSchueler; procedure Clear; procedure LoadFromBinaryTag(const Tag: TRakBinaryTag); procedure SaveToBinaryTag(const Tag: TRakBinaryTag); procedure LoadFromFile(const Filename: String); procedure SaveToFile(const Filename: String); property Count: Integer read GetCount; property Schueler[Index: Integer]: TSchueler read GetSchueler; default; end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TSchueler.LoadFromBinaryTag(const Tag: TRakBinaryTag); begin FName := Tag.AttributeAsString('Name', ''); FVorname := Tag.AttributeAsString('Vorname', ''); FStufe := Tag.AttributeAsInteger('Stufe', 1); end;
procedure TSchueler.SaveToBinaryTag(const Tag: TRakBinaryTag); begin TRakBinaryAnsiString.AddToTag(Tag, 'Name', FName); TRakBinaryAnsiString.AddToTag(Tag, 'Vorname', FVorname); TRakBinaryWord.AddToTag(Tag, 'Stufe', FStufe); end;
function TSchuelerList.AddSchueler: TSchueler; begin Result := TSchueler.Create; FList.Add(Result); end;
procedure TSchuelerList.Clear; begin FList.Clear; end;
constructor TSchuelerList.Create; begin FList := TObjectList.Create; end;
destructor TSchuelerList.Destroy; begin FList.Free;
inherited; end;
function TSchuelerList.GetCount: Integer; begin Result := FList.Count; end;
function TSchuelerList.GetSchueler(Index: Integer): TSchueler; begin Result := TSchueler(FList[Index]); end;
procedure TSchuelerList.LoadFromBinaryTag(const Tag: TRakBinaryTag); var TagList: IRakBinaryTagList; I: integer; begin Clear; TagList := Tag.FindTagsByName('Schueler'); for I := 0 to TagList.Count - 1 do AddSchueler.LoadFromBinaryTag(TagList.Items(I)); end;
procedure TSchuelerList.LoadFromFile(const Filename: String); var Data: TRakBinaryStreamData; begin Data := TRakBinaryStreamData.Create; try if (Data.LoadFromFile(Filename) <> blrOK) or (Data.ApplicationName <> 'Schuelerliste') then begin ShowMessage('Unbekanntes Dateiformat'); end else begin LoadFromBinaryTag(Data); end; finally Data.Free; end; end;
procedure TSchuelerList.SaveToBinaryTag(const Tag: TRakBinaryTag); var I: integer; begin for I := 0 to Count - 1 do Schueler[I].SaveToBinaryTag(Tag.AddTag('Schueler')); end;
procedure TSchuelerList.SaveToFile(const Filename: String); var Data: TRakBinaryStreamData; begin Data := TRakBinaryStreamData.Create; try Data.ApplicationName := 'Schuelerliste'; SaveToBinaryTag(Data); Data.SaveToFile(Filename); finally Data.Free; end; end;
procedure TForm1.FormCreate(Sender: TObject); var Item: TSchueler; begin FSchuelerliste := TSchuelerList.Create;
Item := FSchuelerliste.AddSchueler; Item.Name := 'Müller'; Item.Vorname := 'Lischen'; Item.Stufe := 4;
Item := FSchuelerliste.AddSchueler; Item.Name := 'Rudi'; Item.Vorname := 'Unser'; Item.Stufe := 5;
Item := FSchuelerliste.AddSchueler; Item.Name := 'Musterman'; Item.Vorname := 'Max'; Item.Stufe := 1; end;
procedure TForm1.FormDestroy(Sender: TObject); begin FSchuelerliste.Free; end;
procedure TForm1.BtnSaveClick(Sender: TObject); begin if SaveDialog1.Execute then FSchuelerliste.SaveToFile(SaveDialog1.FileName); end;
procedure TForm1.BtnLoadClick(Sender: TObject); begin if OpenDialog1.Execute then FSchuelerliste.LoadFromFile(OpenDialog1.FileName); end;
end. |
Dadurch, dass jede Information zusammen mit einem Namen abgespeichert wird, ist es kein Problem bei evtl. nicht vorhandene Informationen einen Defaultwert zu setzen.
Das hat allerdings auch Nachteile. Die so erzeugten Dateien sind viel größer, als die, welche durch Pits Code erzeugt werden.
Weiterhin müssen alle Daten erst im Hauptspeicher zwischengepuffert werden, bevor sie auf die Platte geschrieben werden. Für extrem große Datenmengen ist das also nicht so geeignet.
Lass Dich nicht durch den Unfang des Codes abschrecken. Die Codestücke auf die es ankommt sind folgende:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
| procedure TSchuelerList.SaveToFile(const Filename: String); var Data: TRakBinaryStreamData; begin Data := TRakBinaryStreamData.Create; try Data.ApplicationName := 'Schuelerliste'; SaveToBinaryTag(Data); Data.SaveToFile(Filename); finally Data.Free; end; end;
procedure TSchuelerList.SaveToBinaryTag(const Tag: TRakBinaryTag); var I: integer; begin for I := 0 to Count - 1 do Schueler[I].SaveToBinaryTag(Tag.AddTag('Schueler')); end;
procedure TSchueler.SaveToBinaryTag(const Tag: TRakBinaryTag); begin TRakBinaryAnsiString.AddToTag(Tag, 'Name', FName); TRakBinaryAnsiString.AddToTag(Tag, 'Vorname', FVorname); TRakBinaryWord.AddToTag(Tag, 'Stufe', FStufe); end;
procedure TSchuelerList.LoadFromFile(const Filename: String); var Data: TRakBinaryStreamData; begin Data := TRakBinaryStreamData.Create; try if (Data.LoadFromFile(Filename) <> blrOK) or (Data.ApplicationName <> 'Schuelerliste') then begin ShowMessage('Unbekanntes Dateiformat'); end else begin LoadFromBinaryTag(Data); end; finally Data.Free; end; end;
procedure TSchuelerList.LoadFromBinaryTag(const Tag: TRakBinaryTag); var TagList: IRakBinaryTagList; I: integer; begin Clear; TagList := Tag.FindTagsByName('Schueler'); for I := 0 to TagList.Count - 1 do AddSchueler.LoadFromBinaryTag(TagList.Items(I)); end;
procedure TSchueler.LoadFromBinaryTag(const Tag: TRakBinaryTag); begin FName := Tag.AttributeAsString('Name', ''); FVorname := Tag.AttributeAsString('Vorname', ''); FStufe := Tag.AttributeAsInteger('Stufe', 1); end; |
Moderiert von raziel: Code- durch Delphi-Tags ersetzt