Autor |
Beitrag |
Bofrost_Mann
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: Sa 02.02.08 22:14
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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.02.08 16:58
Moin und  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
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Erichgue
      
Beiträge: 86
Win XP/2000/7
TurboPacal 7.0; Delphi 2/5/7; BDS 2006/2010/XE6; C#; MSSQl 2000
|
Verfasst: 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 
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: 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 ...
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
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: 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.
Delphi-Quelltext
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
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Bofrost_Mann 
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: 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 
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: 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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: 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?
Schreib doch einfach direkt die records der Reihe nach in den Stream und gut.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: Mi 06.02.08 09:59
Hallo,
wenn du nur shortstring hast, dann kommst du über die Länge des Streams und Größe deines Records auf die Anzahl der gespeicherten Daten.
Wenn du es völlig dynamisch haben willst, dann schreib als erstes die anzahl in den stream und danach dann die daten, umgedreht dann genauso.
Als Anregung dieser Thread
Gruß Frank
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Bofrost_Mann 
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: 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. 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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 07.02.08 12:20
Moin!
Nochmal:
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?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Bofrost_Mann 
Hält's aus hier
Beiträge: 15
Win XP
Delphi 5, Delphi 2005
|
Verfasst: 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
|
|