![]() |
Array of Record per FileStream speichern
Hallo,
ich habe ewig lange gegoogelt und konnte mein Problem dennoch nicht lösen :( Folgende Situation: Im Browserspiel OGame gibt es Spionageberichte (von den Planeten / Monden anderer Spieler). Damit unsere Allianz (sowas wie ein Clan) immer up-to-date ist im Bezug auf die Berichte, programmiere ich atm an einer kleinen Datenbank. Diese enthält u.A. einen Record für die Erfassung der Informationen, diese wiederum werden in einem Feld gespeichert und sollen (als erster Schritt) in eine Datei geschrieben werden. Folgender Quellcode
Delphi-Quellcode:
Und hier die Speichern- und Laden-Unterprogramme (inklusive Funktion zur Bestimmung der Dateigröße):
type
{ TKoordinaten } TKoordinaten = record Galaxie: 1 .. 9; Sonnensystem: 1 .. 499; Position: 1 .. 15; end; { TTag } TTag = record Tag: 1 .. 31; Monat: 1 .. 12; Jahr: 1900 .. 3000; end; { TZeit } TZeit = record Stunde: 0 .. 23; Minute: 0 .. 59; Sekunde: 0 .. 60; end; { TSpioDB } TSpioDB = record Koordinaten: TKoordinaten; Mond: boolean; Tag: TTag; Zeit: TZeit; Spionagebericht: string; Autor: string; end; { TDB } TDB = array of TSpioDB; { TSpioFile } TSpioFile = File of TSpioDB;
Delphi-Quellcode:
Mein Problem ist jetzt: wenn ich Datensätze anlege (machen andere Unterprogramme fehlerfrei - hab mir nach der Eingabe welche ausgeben lassen) und abspeichere, dannach das Programm neu starte und die Datei öffnen will, werden u.A. "Spionagebericht: string" nicht geladen und können nicht ausgegeben werden.
{ GetFileSizeEx }
function GetFileSizeEx(const AFileName: string): Int64; var F: TSearchRec; begin Result := -1; if FindFirst(AFileName, faAnyFile, F) = 0 then begin try Result := F.FindData.nFileSizeLow or (F.FindData.nFileSizeHigh shl 32); finally SysUtils.FindClose(F); end; end; end; { LoadDatenbank } procedure LoadDatenbank(var db: TDB; var count: integer; s: string; var b: boolean); var spiofile: TSpioFile; i, size, n: integer; begin b := false; size := GetFileSizeEx(s); count := size div sizeof(TSpioDB); SetLength(db, count); try AssignFile(spiofile, s); Reset(spiofile); for i := Low(db) to (High(db) - 1) do Read(spiofile, db[i]); b := true; finally CloseFile(spiofile); end; end; { SaveDatenbank } function SaveDatenbank(db: TDB; s: string): boolean; var spiofile: TSpioFile; i: integer; begin result := false; try AssignFile(spiofile, s); Rewrite(spiofile); for i := Low(db) to (High(db) - 1) do Write(spiofile, db[i]); result := true; finally CloseFile(spiofile); end; end; Kann mir jemand helfen? Wenn irgendwas unklar ist dann nochmal nachfragen, kann auch sein, dass ich jetzt irgendwas wichtiges vergessen habe :pale: Danke im Vorraus LG Glocke |
Re: File of Array
String kannst Du in einer typisierten Datei nicht verwenden. String enthält grob gesagt nur einen Zeiger auf die Zeichenkette, Du speicherst also nur den Zeiger.
Die Zeichen sind zudem von variabler Länge, was eine typisierte Datei auch nicht mag. Entweder änderst Du String nach ShortString (also String[255]) oder wenn 255 Zeichen nicht reichen, dann array of Char oder anders Speicher-System. ![]() |
Re: File of Array
es gibt sogar schon tausende Theman zu dieser Angelegenheit ... der Letze ist nichtmal alt
![]() ![]() |
Re: File of Array
Zitat:
/EDIT
Delphi-Quellcode:
wenn ich zB
dbengine.pas(166,26) Error: Incompatible types: got "Open Array Of Char" expected "Dynamic Array Of Char"
Delphi-Quellcode:
machen will.
db[count - 1].Autor := a;
PS: String[255] reicht glaube ich nicht aus... |
Re: File of Array
Das Problem
Delphi-Quellcode:
wird in den benanten Thread behandelt...
Incompatible types: got "Open Array Of Char" expected "Dynamic Array Of Char"
Nebenbei... es bleibt dabei... keine dynamischen Strukturen für eine typisierte Datei. Das gilt dann auch für ein Array. |
Re: File of Array
Ich merk gerade es geht auch ganz anders:
Die Spionageberichte kann ich auch direkt in die Unterpunkte "Rohstoffe", "Gebäude" etc. zerlegen, da reichen 255 Zeichen aus ... ich schau mir das mit dem Array of Char trotzdem der Vollständigkeit halber mal an. Nochmal danke für die Erinnerung mit dem String, dass der nen Zeiger enthält :duck: So... mittlerweile bin ich über ![]()
Delphi-Quellcode:
Mir fehlt beim "Laden" die Bedingung wann meine Schleife (die alle Elemente auslesen soll) abbrechen soll.
procedure SaveDatenbank(x: TDB; Filename: String);
var fs: TFileStream; l, i: Integer; begin fs := TFilestream.Create(Filename, fmCreate); try for i := 0 to High(x) do begin fs.Write(x[i].Koordinaten, SizeOf(TKoordinaten)); fs.Write(x[i].Mond, SizeOf(boolean)); fs.Write(x[i].Tag, SizeOf(TTag)); fs.Write(x[i].Zeit, SizeOf(TZeit)); l := Length(x[i].Spionagebericht); fs.Write(l, SizeOf(string)); fs.Write(x[i].Spionagebericht, l); l := Length(x[i].Autor); fs.Write(l, SizeOf(string)); fs.Write(x[i].Autor, l); end; finally fs.Free; end; end; // ----------------------------------------------------------------------------- function LoadDatenbank(Filename: String): TDB; var fs: TFileStream; l, i: Integer; begin fs := TFilestream.Create(Filename, fmOpenRead); try i := 0; while { hier fehlt mir irgendeine Bedingung } do begin fs.Read(Result[i].Koordinaten, SizeOf(TKoordinaten)); fs.Read(Result[i].Mond, SizeOf(boolean)); fs.Read(Result[i].Tag, SizeOf(TTag)); fs.Read(Result[i].Zeit, SizeOf(TZeit)); fs.Read(l, SizeOf(string)); SetLength(Result[i].Spionagebericht, l); fs.Read(Result[i].Spionagebericht, l); fs.Read(l, SizeOf(string)); SetLength(Result[i].Autor, l); fs.Read(Result[i].Spionagebericht, l); i := i + 1; end; finally fs.Free; end; end; Ich hab einen Zähler (i) eingefügt um die einzelnen Elemente des Arrays anzusprechen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:36 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