Entwickler-Ecke
Dateizugriff - Typisierte Datei hat plötzlich ganz anderen Inhalt
bfelix - So 13.02.11 16:26
Titel: Typisierte Datei hat plötzlich ganz anderen Inhalt
Hallo Community,
ich habe aus diesem Tutorial:
http://www.delphi-treff.de/tutorials/datenspeicherung/typisierte-dateien/einleitung/ den Code genommen (ich denke auch verstanden) und nur den Record abgeändert und natürlich die zugehörigen Codeteile:
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: 188: 189: 190: 191: 192: 193: 194:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type ereignistype = record ereignis: string[255]; AnBank: integer; VonBank: integer; AnSpieler: integer; VonSpieler: integer; gefaengnis: integer; end; TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; Button7: TButton; Edit5: TEdit; Edit6: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure positionieren(datensatz: integer); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button7Click(Sender: TObject); private public end;
var Form1: TForm1; datei: file of ereignistype; const BufferSize = 32;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); var path: String; begin AssignFile(datei, 'ereignisse.med'); if FileExists('adressen.med') then ReSet(datei) else ReWrite(datei); end;
procedure TForm1.FormDestroy(Sender: TObject); begin CloseFile(datei); end;
procedure TForm1.positionieren(datensatz: integer); var aktdatensatz: ereignistype; begin if (datensatz<0) or (datensatz>=FileSize(datei)) then exit else begin seek(datei, datensatz); read(datei, aktdatensatz); edit1.text:=aktdatensatz.ereignis; edit2.text:=InttoStr(aktdatensatz.AnBank); edit3.text:=InttoStr(aktdatensatz.VonBank); edit4.text:=InttoStr(aktdatensatz.AnSpieler); edit5.text:=InttoStr(aktdatensatz.VonSpieler); edit6.text:=InttoStr(aktdatensatz.gefaengnis); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin positionieren(0); end;
procedure TForm1.Button2Click(Sender: TObject); begin positionieren(FilePos(datei)-2); end;
procedure TForm1.Button3Click(Sender: TObject); begin positionieren(FilePos(datei)); end;
procedure TForm1.Button4Click(Sender: TObject); begin positionieren(FileSize(datei)-1); end;
procedure TForm1.Button6Click(Sender: TObject); var Buffer: array[0..BufferSize - 1] of ereignistype; i, p: Integer; StartRecord, EndRecord: Integer; Max: Integer; begin Seek(Datei, FilePos(Datei)-1); StartRecord := FilePos(Datei) + 1; EndRecord := FileSize(Datei);
while StartRecord < EndRecord do begin
Max := BufferSize; if Max > EndRecord - StartRecord then Max := EndRecord - StartRecord; Seek(Datei, StartRecord); for i := 0 to Max - 1 do Read(Datei, Buffer[i]);
Seek(Datei, StartRecord - 1); for i := 0 to Max - 1 do Write(Datei, Buffer[i]); inc(StartRecord); end;
Truncate(Datei); Positionieren(StartRecord-1); end;
procedure TForm1.Button5Click(Sender: TObject); var Buffer: array[0..BufferSize - 1] of ereignistype; i, p: integer; begin Seek(datei,0); p:=0; while not eof(datei) do begin Read(datei, Buffer[p]); inc(p); end; CloseFile(datei); Buffer[p+1].ereignis:=''; Buffer[p+1].AnBank:=0; Buffer[p+1].VonBank:=0; Buffer[p+1].AnSpieler:=0; Buffer[p+1].VonSpieler:=0; Buffer[p+1].gefaengnis:=0; ReWrite(datei); for i:=0 to p do write(datei, Buffer[i]); positionieren(FileSize(datei)-1); end;
procedure TForm1.Button7Click(Sender: TObject); var datensatz: ereignistype; nr: integer; begin Seek(Datei,FilePos(Datei)); nr:=FilePos(datei); datensatz.ereignis:=Edit1.Text; datensatz.AnBank:=StrtoInt(Edit2.Text);
datensatz.VonBank:=StrtoInt(Edit3.Text);
datensatz.AnSpieler:=StrtoInt(Edit4.Text); datensatz.VonSpieler:=StrtoInt(Edit5.Text); datensatz.gefaengnis:=StrtoInt(Edit6.Text); write(datei,datensatz); positionieren(nr); end;
end. |
Nun habe ich versucht, die Datei in einem anderen Programm weiterzuverarbeiten. Leider haben sich allerdings in der Datei die Datensätze 'verselbstständigt' und es finden sich die erstellten Datensätze völlig durchgemischt und es existieren unzurückführbare Datensätzen mit komischen Zeichenfolgen und Nummern. Wenn ich das Programm von oben aufrufe, finde ich eine scheinbar leere Datei vor. Hat irgendwer eine Idee, was passiert sein könnte?
Zusatzinformation: Ich benutze Delphi 7 unter Windows 7 und XP
Danke,
BFelix
Mr_Emre_D - So 13.02.11 17:19
Edit: Sry, Denkfehler
bfelix - So 13.02.11 21:28
Hallo? Hat hier irgendwer noch eine Idee?
ich kann mir überhaupt nicht vvorstellen was mit der Datei passiert ist
Delete - So 13.02.11 22:03
Schon mal auf die Idee gekommen, dass er die Datei nicht findet:
Delphi-Quelltext
1:
| AssignFile(datei, 'ereignisse.med'); |
jaenicke - So 13.02.11 23:04
Auf die Idee gekommen wohl schon, aber...
bfelix hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.FormCreate(Sender: TObject); var path: String; begin AssignFile(datei, 'ereignisse.med'); if FileExists('adressen.med') then ReSet(datei) else ReWrite(datei); end; | |
:nut:
Tranx - Mo 14.02.11 04:34
Das, was Jänicke schreibt, wäre zu überprüfen. Ob Du vielleicht die falsche Datei aufrufst. Aber das würde ja nicht erklären, dass die Datensätze völlig durchmischt sind.
Wann tritt der Effekt auf? So im Überblick scheint alles andere in Ordnung zu sein. Aber der Teufel steckt ja bekanntlich im Detail. Da hilft nur das Debuggen. Setze einen Haltepunkt - ich denbke, die Click-Routine von Button6 wäre da geeignet - und prüfe, was da gelesen wird. Und natürlich, was dann zum Schluss geschrieben wird.
jasocul - Mo 14.02.11 09:33
bfelix hat folgendes geschrieben : |
Nun habe ich versucht, die Datei in einem anderen Programm weiterzuverarbeiten. Leider haben sich allerdings in der Datei die Datensätze 'verselbstständigt' und es finden sich die erstellten Datensätze völlig durchgemischt und es existieren unzurückführbare Datensätzen mit komischen Zeichenfolgen und Nummern. Wenn ich das Programm von oben aufrufe, finde ich eine scheinbar leere Datei vor. Hat irgendwer eine Idee, was passiert sein könnte |
Ich gehe erstmal auf das Problem mit den komischen Zeichenfolgen ein:
Das ist ein typisches Phänomen, wenn bei typisierten Dateien mit der falschen Record-Struktur zugegriffen wird. Also eine andere Feldgröße, ein neues Feld oder es wurde eins gelöscht. Aber ich vermute hier eher einen anderen Fehler. In dem einen Programm wird mit packed-Records gearbeitet und in dem anderen nicht. Dadurch wird ein Programm die Daten mit einem leichten Versatz lesen. Das Problem behebst du, indem du das angleichst. Das geht über einen Compiler-Schalter, den ich im Moment allerdings nicht im Kopf habe. Dürfte für dich aber nicht schwer sein, das herauszufinden.
Das die Datensätze durcheinander erscheinen, ist vermutlich eine Folge aus dem ersten Problem. Strings werden in Delphi mit einem Längenbyte an Stelle 0 versehen, damit Delphi weiß, was alles zum String gehört. (An den Rest der Welt: Ich weiß, dass Delphi auch nullterminierte Strings kennt, das spielt hier aber keine Rolle.) Wird jetzt mit Versatz gelesen, werden "Mülldaten" mit eingelesen, die unter Umständen zu alten oder anderen Einträgen gehören.
Und wie die Anderen schon geschrieben haben, kann es natürlich auch sein, dass du eine völlig falsche Datei verwendest.
jaenicke - Mo 14.02.11 09:54
jasocul hat folgendes geschrieben : |
Das ist ein typisches Phänomen, wenn bei typisierten Dateien mit der falschen Record-Struktur zugegriffen wird. Also eine andere Feldgröße, ein neues Feld oder es wurde eins gelöscht. |
Genau das ist einer der Gründe warum ich typisierte Dateien nicht nutze. Wenn ich Klassen benutze, die sich um das serialisieren der Daten kümmern, kann ich einfach zuerst das Speichern anpassen und dann das Lesen und zack, sind die Daten im neuen Format. Oder man kann besser gleich alles versionsspezifisch einbauen, denn bei Klassen ist ja auch das kein Problem (anders als bei typisierten Dateien, insbesondere ohne Kapselung in Klassen).
bfelix - Mo 14.02.11 22:13
Weiß jemand, wo ich diesen Compilerschalter finde oder kann mir jemand sagen, was das ist?
bfelix - Di 15.02.11 18:01
Hallo,
ich habe jetzt erste entdeckt dass ich ein Feld in einem hatte und im anderen nicht.
Danke
BFelix
jaenicke - Di 15.02.11 19:59
Wenn es sich um zwei Programme handelt, dann pack die gemeinsamen Deklarationen wie den Record in eine Unit, die du dann in beide Projekte einbindest...
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!