Entwickler-Ecke
Dateizugriff - Fehler beim Speichern von TFileStream
Bofrost_Mann - Sa 02.02.08 22:14
Titel: Fehler beim Speichern von TFileStream
Hallo, ich bin vollkommen neu auf dem Gebiet von FileStreams und möchte zwei Records in eine Datei schreiben und diese natürlich auch wieder lesen. Ich bin gerade dabei das ganze rein funktional zu testen um mit dem ganzen dann später den Datenaustausch für ein schon bestehendes Programm zu organisieren werden, was bis jetzt auf Basis von Textdateien funktioniert.
Starte ich das Programm in Delphi scheint das Speichern und Laden auch zu funktionieren, doch will ich es beenden erscheint eine Fehlermeldung:
"mit ...\Project1.exe trat ein Problem auf ... access violation at ... write of adress ...".
Starte ich die compilierte *.exe erscheint keine Fehlermeldung beim schließen, wenn die Datei mit der selpen Compilierung erstellt wurde.
Was hat es mit dieser Meldung auf sich bzw. wo liegt der Fehler?
-----
Wurde die Datei mit einer älteren Compilierung erstellt und soll sie geladen werden, erscheint eine Fehlermeldung. Die Frage hierzu: ist es möglich auch Dateien älterer Compilierungen wieder einzulesen.
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: 24: 25: 26: 27: 28: 29:
| procedure TForm1.SaveVars; var Stream:TFileStream; SchreibBuch: array [1..2] of Katalog; begin SchreibBuch[1]:=Buch[1]; SchreibBuch[2]:=Buch[2];
Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmCreate); try Stream.WriteBuffer(SchreibBuch,SizeOf(SchreibBuch)); Stream.WriteBuffer(ProgrammVersion,SizeOf(ProgrammVersion)); finally Stream.Free; end; end; procedure TForm1.LoadVars; var Stream:TFileStream; begin Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmOpenRead); try Stream.ReadBuffer(LeseBuch,SizeOf(LeseBuch)); Stream.ReadBuffer(ProgrammVersion,SizeOf(ProgrammVersion)); finally Stream.Free; end; end; |
Schonmal Danke für Eure Antworten.
Narses - Mo 04.02.08 16:58
Titel: Re: Fehler beim Speichern von TFileStream
Moin und :welcome: im Forum!
Bofrost_Mann hat folgendes geschrieben: |
Was hat es mit dieser Meldung auf sich bzw. wo liegt der Fehler?
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.SaveVars; var Stream:TFileStream; SchreibBuch: array [1..2] of Katalog; begin | |
Um deine Frage beantworten zu können, benötigen wir noch die Deklaration des Typs
Katalog.
cu
Narses
Erichgue - Mo 04.02.08 17:35
Zitat: |
Starte ich das Programm in Delphi scheint das Speichern und Laden auch zu funktionieren, doch will ich es beenden erscheint eine Fehlermeldung: |
Was machst du denn beim Beenden?
Zeigt mal etwas Code!
Erich
Bofrost_Mann - Di 05.02.08 17:55
hier mal der komplette code der unit ... diese unit soll erstmal nur "symbolcharakter" haben und rein funktionell einwandfrei arbeiten ...
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: 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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Edit7: TEdit; Edit8: TEdit; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject);
private procedure LoadVars; procedure SaveVars; public end;
type Katalog=record Name: string; Vorname: string; end;
type Version=record Programm: integer; Adressbuch: integer; end;
var Form1: TForm1; Buch: array [1..2] of Katalog; LeseBuch: array [1..2] of Katalog;
ProgrammVersion: Version;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); begin buch[1].name:='nachname1'; buch[1].vorname:='rufname1';
buch[2].name:='nachname2'; buch[2].vorname:='rufname2';
ProgrammVersion.Programm:=1; ProgrammVersion.Adressbuch:=0;
edit1.text:=buch[1].name; edit2.text:=buch[1].vorname; edit3.text:=buch[2].name; edit4.text:=buch[2].vorname; end;
procedure TForm1.SaveVars; var Stream:TFileStream; SchreibBuch: array [1..2] of Katalog; begin SchreibBuch[1]:=Buch[1]; SchreibBuch[2]:=Buch[2];
Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmCreate); try Stream.WriteBuffer(SchreibBuch,SizeOf(SchreibBuch)); Stream.WriteBuffer(ProgrammVersion,SizeOf(ProgrammVersion)); finally Stream.Free; end; end; procedure TForm1.LoadVars; var Stream:TFileStream; begin Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmOpenRead); try Stream.ReadBuffer(LeseBuch,SizeOf(LeseBuch)); Stream.ReadBuffer(ProgrammVersion,SizeOf(ProgrammVersion)); finally Stream.Free; end; end;
procedure TForm1.Button1Click(Sender: TObject); begin savevars; button1.enabled:=false; end;
procedure TForm1.Button2Click(Sender: TObject); begin loadvars;
edit5.text:=LeseBuch[1].name; edit6.text:=LeseBuch[1].vorname; edit7.text:=LeseBuch[2].name; edit8.text:=LeseBuch[2].vorname; end;
end. |
Keldorn - Di 05.02.08 18:18
Hallo
in deinem Record ist ein string enthalten, da wird das nix, weil die eigentliche Länge nicht bekannt ist.
laß dir das mal in einer messagebox anzeigen.
Entweder, du nimmst strings mit einer festen länge
Delphi-Quelltext
1: 2: 3: 4:
| type Katalog=record Name: string[30]; Vorname: string[30]; end; |
oder besser, such mal im Forum, Fragen zu strings und stream gibts recht häufig, oder du guggst mal nach
TREADER und
TWRITER, damit machst du dir das Leben auch leichter.
Gruß Frank
Bofrost_Mann - Di 05.02.08 21:44
Danke an alle, für Eure Tipps. Ich hab in Katalog die Strings jetzt als shortstring deklariert und bekomm auch keine fehler mehr. Das Einlesen von Dateien älterer Compilierungen scheint auch Problemlos zu funktionieren.
Bofrost_Mann - Di 05.02.08 22:24
Habe doch noch ein kleines Problem: kann ich das ganze auch dynamisch vereinbaren? D.h. ein Array mit dynamischer Länge Speichern und dann auch wieder lesen?
Folgender Versuch brachte Fehler:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.SaveVars; var Stream:TFileStream; SchreibBuch: array of Katalog; begin
setlength(Schreibbuch, 3);
SchreibBuch[1]:=Buch[1]; SchreibBuch[2]:=Buch[2]; |
Narses - Di 05.02.08 22:45
Moin!
Bofrost_Mann hat folgendes geschrieben: |
kann ich das ganze auch dynamisch vereinbaren? D.h. ein Array mit dynamischer Länge Speichern und dann auch wieder lesen? |
Wozu überhaupt dieses Array als Umweg zum Speichern? :gruebel:
Schreib doch einfach direkt die records der Reihe nach in den Stream und gut. :nixweiss: :idea:
cu
Narses
Bofrost_Mann - Mi 06.02.08 14:31
Hallo, und nochmal Danke an alle für die schnellen Antworten. Habe das Speichern und Laden jetzt über Treader und Twriter organisiert (thx@ Keldorn). Ich hänge den jetzigen Quelltext nocheinmal an, falls andere ähnliche Probleme haben und Anregungen suchen.
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: 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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Edit7: TEdit; Edit8: TEdit; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject);
private procedure LoadVars; procedure SaveVars;
public end;
type Katalog=record Name: string; Vorname: string; end;
type Version=record Programm: integer; Adressbuch: integer; end;
var Form1: TForm1; Buch: array of Katalog; LeseBuch: array of Katalog;
ProgrammVersion: Version; LeseProgrammVersion: Version;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); begin setlength(buch, 3);
buch[0].name:=''; buch[0].vorname:='';
buch[1].name:='nachname1'; buch[1].vorname:='rufname1';
buch[2].name:='nachname2'; buch[2].vorname:='rufname2';
ProgrammVersion.Programm:=1; ProgrammVersion.Adressbuch:=0;
edit1.text:=buch[1].name; edit2.text:=buch[1].vorname; edit3.text:=buch[2].name; edit4.text:=buch[2].vorname; end;
procedure TForm1.SaveVars; var Stream:TFileStream; SchreibBuch: array of Katalog; i: integer; begin
setlength(Schreibbuch, length(buch)); for i:=0 to length(buch)-1 do SchreibBuch[i]:=Buch[i]; Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmCreate); try
begin with Twriter.create(Stream,1024) do begin try begin writeinteger(ProgrammVersion.Programm); writeinteger(ProgrammVersion.Adressbuch);
writeinteger(length(schreibBuch)); for i:=0 to length(schreibBuch)-1 do begin writestring(schreibbuch[i].Name); writestring(schreibbuch[i].Vorname); end; end; finally free; end; end; end;
finally
Stream.Free;
end;
end; procedure TForm1.LoadVars; var Stream:TFileStream; i:integer; anzahl: integer; begin
Stream:=TFileStream.Create('C:\Speicher\Test.adb', fmOpenRead);
try
begin with Treader.create(Stream,1024) do begin try begin LeseProgrammVersion.Programm:=readinteger; LeseProgrammVersion.Adressbuch:=readinteger;
anzahl:=readinteger; setlength(lesebuch, anzahl); for i:=0 to anzahl-1 do begin lesebuch[i].Name:=readstring; lesebuch[i].Vorname:=readstring; end; end; finally free; end; end; end;
finally
Stream.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject); begin savevars; button1.enabled:=false; end;
procedure TForm1.Button2Click(Sender: TObject); begin loadvars;
Form1.caption:='Kontakte Version '+inttostr(LeseProgrammVersion.Programm)+'.'+inttostr(LeseProgrammVersion.Adressbuch);
edit5.text:=LeseBuch[1].name; edit6.text:=LeseBuch[1].vorname; edit7.text:=LeseBuch[2].name; edit8.text:=LeseBuch[2].vorname; end;
end. |
Liebe Grüße
Der Bofrost Mann
Narses - Do 07.02.08 12:20
Moin!
Nochmal: :roll:
Bofrost_Mann hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.SaveVars; setlength(Schreibbuch, length(buch)); for i:=0 to length(buch)-1 do SchreibBuch[i]:=Buch[i]; for i:=0 to length(schreibBuch)-1 do begin writestring(schreibbuch[i].Name); writestring(schreibbuch[i].Vorname); | |
Wozu kopierst du die Werte, hast du zuviel Speicher? :nixweiss: ;)
cu
Narses
Bofrost_Mann - Do 07.02.08 15:06
@narses: wie gesagt das Speichern und Lesen sollte nur rein funktionell einwandfrei arbeiten ... das Kopieren des Array-Records war auch nur mal für Testzwecke ... mittlerweile hab ich das Konzept in dem anderen Programm umgesetzt und dort gibts natürlich vorher keine Kopie des Arrays ...
LG Der Bofrost Mann
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!