Entwickler-Ecke

Dateizugriff - file of dynamic array of trecord


chillywilly - Mo 21.11.05 17:57
Titel: file of dynamic array of trecord
Hiho erstma,
wie der Titel ja schon sagt geht es ums auslesen und schreiben eines dynamischen arrays (also ohne feste länge) eines TRecords.
in diesem Fall habe ich in meinem Record 3 Felder vom typ integer, string, string.

mein problem ist nun das zur programm laufzeit die länge des arrays verändert wird. ich will nun zb beim beenden des programms dieses array in einer datei des selben typs absspeichern und bei neustart des programms mein array mit SELBER LÄNGE WIE in das array laden.

hoffe ihr könnt erahnen was ich meine.

die deklaration sieht bei mir so aus:


Delphi-Quelltext
1:
2:
var list : array of TMyList;
    flist: file of TMyList;



help plz ^^

mika

Moderiert von user profile iconChristian S.: Buchstabengewirr aus Titel entfernt ...
Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt


BenBE - Mo 21.11.05 18:15

Zuerst einmal ein paar Anmerkungen vorweg: Strings in Records speichern, wenn diese in eine Datei sollen, ist das schlimmste, was man machen kann ;-)

In der Omorphia Library gibt es eine erweiterte Stream-Klasse TOVCLToVFSStream, mit der Du einen TFileStream kapseln kannst und damit sehr einfach Zugriff zum Schreiben von Strings in und lesen von Strings aus Streams hast (sowie viele andere Datentypen. Die nötigen Units finden sich im Repository von Projekt Omorphia [http://viewcvs.omorphia.de/omorphia/library/source/]. Näheres dazu kann ich auf Nachfrage ausführen.

Allgemein wirst Du bei deiner jetzigen Struktur sehr viel manuell machen müssen ...

Versuche auf ShortStrings umzusteigen, da diese eine feste Größe haben ...


chillywilly - Mo 21.11.05 18:21

das auf shortstring umsteigen is kein problem.

nur das mit dem dynamic array in datei abspeichern mit file of bekomm ich net gebacken


hier mal das abspeichern:


Delphi-Quelltext
1:
2:
3:
4:
   AssignFile(f_user_list, 'data\user_db.dat');
   Rewrite(f_user_list);
   Write(user_list);
   close(f_user_list);


BenBE - Mo 21.11.05 18:27

File Of TRecord ist bereits ein "dynamisches Array" in der Datei ... Du schreibst einfach alle deine Datensätze (Einträge) aus dem Array einzeln rein.

//Edit: Die Länge ermittelst Du einfach mit FileSize div SizeOf(TRecord).


chillywilly - Mo 21.11.05 18:40

Der Fehler kommt immer bei der write anweisung

also bei write(user_list); :
[Fehler] server_unit.pas(82): Ungültiger Typ in Write/Writeln-Anweisung

doof!


BenBE - Mo 21.11.05 18:48

Änder
user profile iconchillywilly hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
   AssignFile(f_user_list, 'data\user_db.dat');
   Rewrite(f_user_list);
   Write(user_list);
   close(f_user_list);

mal so hier ab

Delphi-Quelltext
1:
2:
3:
4:
5:
   AssignFile(f_user_list, 'data\user_db.dat');
   Rewrite(f_user_list);
   for X := 0 TO High(user_list) do
      Write(user_list[X]);
   close(f_user_list);


Dann sollte das funzen ...


chillywilly - Mo 21.11.05 18:58

wieder fehler beim schreiben:
[Fehler] server_unit.pas(82): Ungültiger Typ in Write/Writeln-Anweisung

vielleicht mal hier die dekla von meinem record:



Delphi-Quelltext
1:
2:
3:
4:
5:
  Tuser_list = record
   user_id      : integer;
   user_email   : shortstring;
   user_passwd  : shortstring;
  end;


BenBE - Mo 21.11.05 19:07

Wie ist deine Datei deklariert?

Datei : File of TRecord;?


chillywilly - Mo 21.11.05 19:18

ne als file of Tuser_list


BenBE - Mo 21.11.05 19:32

Man sollte vielleicht auch noch ein Ziel angeben ;-)


Delphi-Quelltext
1:
2:
3:
4:
5:
   AssignFile(f_user_list, 'data\user_db.dat');
   Rewrite(f_user_list);
   for X := 0 TO High(user_list) do
      Write(f_user_list, user_list[X]);
   close(f_user_list);


Damit sollte er jetzt nicht mehr meckern ^^


chillywilly - Mo 21.11.05 19:35

yeah ^^ haste vielleicht auch noch ne prozedur für anders rum?

also von datei zum dynmaschin array meines records? wäre sehr toll!


chillywilly - Mo 21.11.05 20:18

Hab mich mal an die lesefunktion gemacht, nur meckert der nun immer das bei read inkompatible typen sind. Tuser_list und dynamix array :/


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
   try
    AssignFile(f_user_list, 'data\user_db.dat');
    Reset(f_user_list);
    Read(f_user_list, user_list);
    close(f_user_list);
    write('done.'+#13+#10);
   finally
    write('error!'+#13+#10);
   end;


BenBE - Mo 21.11.05 20:39

Du musst auch beim Lesen Record-weise auslesen.

Die Größe für dein Array musst Du vorher einmalig aus Dateigröße div SizeOf(TRecord) ermitteln und mit SetLength setzen..


chillywilly - Mo 21.11.05 21:06


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
   try
    AssignFile(f_user_list, 'data\user_db.dat');
    Reset(f_user_list);
    while not EOF do begin
     setLength(user_list, Length(user_list)+1);
     Read(f_user_list, user_list[Length(user_list)-1]);
     writeln(user_list[Length(user_list)-1].user_email);
    end;
    close(f_user_list);
    write('done.'+#13+#10);
   except
    write('error!'+#13+#10);
   end;


Hab noch einen Fehler :/ der liest und liest und liest (bis ins unendliche)
aber er liest schonmal die sachen aus die er soll :)


Horst_H - Di 22.11.05 14:37

Hallo,

es gibt so schoene Funktionen wie
filesize(f_user_list)
filepos(f_user_list)
Seek(f_user_list,NeueRecordPosition)
Filesize=> Anzahl der records
Ein file of ?? ist wie ein dynamisches array 0 basiert.
Filesize 10-> Ende bei 9.

Also hier [http://www.delphibasics.co.uk/ByUnit.asp?Unit=System] und natuerlich in der Delphi Hilfe zur Unit system (immer automatisch dabei) steht genug dazu.

Gruss Horst