[gelöst] Filestream tList Record

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
exc-jdbi
Beiträge: 64
Registriert: So 3. Aug 2014, 03:37

[gelöst] Filestream tList Record

Beitrag von exc-jdbi »

Guten Abend Community

Es geht um das Abspeichern einer tList mit Record.

Das ist die Routine,
http://www.lazarusforum.de/viewtopic.php?f=55&t=8120
die ich versuchshalber genommen habe, um die Filestream-Methode näher unter die Lupe zu nehmen, da es sich um sehr viel Daten handelt.

Die Routine funktioniert so wie Theo das beschrieben hat einwandfrei. Jedoch wenn ich mit Filstream arbeite und diese zuerst abspeichere und nachher wieder Lade, erscheint eine Fehlermeldung (siehe Bild) sobald ich das Programm beende.

Auch ist mir aufgefallen, dass das Einlesen von der Festplatte nicht perfekt funktioniert. Nach Kontrolle mit

Code: Alles auswählen

 
iCount:=liste.Count;			        //>> 1000 		    Richtig
str:=pName(Liste[0])^.Vorname;		 //>> Vorname0		 Richtig
str:=pName(Liste[0])^.Nachname;		//>> Nachname0		Richtig
str:=pName(Liste[1])^.Vorname;		 //>> Vorname1		 Richtig
str:=pName(Liste[1])^.Nachname;		//>> Nachname1		Richtig
str:=pName(Liste[10])^.Vorname;		//>> ''  		     Falsch!
str:=pName(Liste[10])^.Nachname;	  //>> ''  		     Falsch!
 
sind die ersten paar Werte richtige, jedoch ab ca. der 10ten (str:=pName(Liste[10])^.Vorname;) besitzt die 'str'-Variable keinen Wert mehr.

Habe ich da irgend etwas beim Laden übersehen? Muss ich die Strings vielleicht einzel speichern?


Abspeichern:

Code: Alles auswählen

 
procedure TForm1.SaveClick(Sender: TObject);
var iCount:int32;
    fs:tFileStream;
    FileName:string='SortList.txt';
begin
  try
    fs:=tFileStream.Create(FileName,fmCreate or fmShareDenyNone);
    for iCount:= 0 to Liste.Count-1 do
      fs.Write(Liste[iCount]^,SizeOf(tName));
  finally
    FreeAndNil(fs);
  end;
end;
 
Laden:

Code: Alles auswählen

 
procedure TForm1.LoadClick(Sender: TObject);
var str:string;
    pN:pName;
    fs:tFilestream;
    iCount,nCount:integer;
    FileName:string='SortList.txt'; 
begin
  {'Liste' wird vorgängig komplett bereinigt und geCleart und auf NIL gesetzt,
  und wieder neu geCreatet}
 
  if FileExists(FileName) then
    if Assigned(Liste) then
    begin
      try
        fs:=tFileStream.Create(FileName,fmOpenReadWrite or fmShareDenyWrite);
        nCount:=fs.Size div SizeOf(tName);
        liste.Capacity:=nCount;
 
        for iCount:=0 to nCount-1 do
        begin
          New(pN);
          fs.Read(pN^,SizeOf(tName));
          Liste.Add(pN);
        end;
      finally
        FreeAndNil(fs);
      end;
    end;
end;
 
Die Fehlermeldung, die Ausgegeben wird, beim schliessen der Form
Die Fehlermeldung, die Ausgegeben wird, beim schliessen der Form
Fehlermeldung.jpg (11.08 KiB) 571 mal betrachtet
Hier noch die Assembler Daten
Hier noch die Assembler Daten
Danke für die Hilfe

Freundliche Grüsse

exc-jdbi
Zuletzt geändert von exc-jdbi am So 5. Okt 2014, 13:38, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Filestream tList Record

Beitrag von theo »

Das hat wahrsch. damit zu tun, dass im Modus {$H+} der String ein AnsiString ist.
Also im Prinzip nur ein Pointer.
Oder wie stellst du dir vor, dass SizeOf(tName)) sich an die Länge des String Inhalts anpasst?
SizeOf(tName)) ist immer gleich.

Bau deinen Record mit Strings fester Länge, z.B. String[20] oder schreibe die tatsächliche Länge length(S) des AnsiStrings in die Datei.
TFileStream, resp. TStream kennt auch die Methode WriteAnsiString();

exc-jdbi
Beiträge: 64
Registriert: So 3. Aug 2014, 03:37

Re: Filestream tList Record

Beitrag von exc-jdbi »

Logo, Wie konnte ich das jetzt auch übersehen. :shock:
Danke Theo.


Freundliche Grüsse

exc-jdbi

Antworten