Autor Beitrag
bfelix
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61

WIN 2000 Prof., Win XP Prof., Win 7 Starter und Prof., SuSe Linux 11.3,
Delphi 7 Pers.
BeitragVerfasst: So 13.02.11 16:26 
Hallo Community,
ich habe aus diesem Tutorial: www.delphi-treff.de/...-dateien/einleitung/ den Code genommen (ich denke auch verstanden) und nur den Record abgeändert und natürlich die zugehörigen Codeteile:
ausblenden volle Höhe 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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<0or (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 - 1of ereignistype;  // erhöht Performance
  i, p: Integer;
  StartRecord, EndRecord: Integer;
  Max: Integer;
begin
  // Datenzeiger wird VOR den akt. Datensatz gesetzt
  Seek(Datei, FilePos(Datei)-1);
  // Starten mit dem ersten Datensatz hinter dem zu löschenden
  StartRecord := FilePos(Datei) + 1;
  EndRecord := FileSize(Datei);

  while StartRecord < EndRecord do begin

    // max. BufferSize Datensätze lesen
    Max := BufferSize;
    if Max > EndRecord - StartRecord then
      Max := EndRecord - StartRecord;
    Seek(Datei, StartRecord);
    for i := 0 to Max - 1 do
      Read(Datei, Buffer[i]);

    // Datensätze zurückschreiben
    Seek(Datei, StartRecord - 1);
    for i := 0 to Max - 1 do
      Write(Datei, Buffer[i]);
    inc(StartRecord);
  end;

  // Datei ab hier abschneiden
  Truncate(Datei);
  Positionieren(StartRecord-1);
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  Buffer: array[0..BufferSize - 1of ereignistype;
  i, p: integer;
begin
  Seek(datei,0);
  p:=0;
  while not eof(datei) do begin //solange lesen, bis die Datei zu Ende ist
    Read(datei, Buffer[p]);
    inc(p); //entspr. p:=p+1
  end;
  CloseFile(datei); //Datei schließen...
  Buffer[p+1].ereignis:=''//Am Ende leeren Datensatz anhängen
  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);  //... und neu anlegen
  for i:=0 to p do write(datei, Buffer[i]);
  //Datensätze (bis auf letzten) in Datei schreiben
  positionieren(FileSize(datei)-1);
  //Dateizeiger auf letzten Datensatz positionieren
end;

procedure TForm1.Button7Click(Sender: TObject);
var datensatz: ereignistype;
    nr: integer;
begin
  // Datenzeiger VOR den aktuellen Datensatz setzen
  Seek(Datei,FilePos(Datei));
  nr:=FilePos(datei);
  datensatz.ereignis:=Edit1.Text;
  datensatz.AnBank:=StrtoInt(Edit2.Text);

  //hier müsste eine Prüfung stattfinden, ob eine Zahl eingegeben wurde!
  //Falls keine gültige Zahl, wird -1 gespeichert
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 114
Erhaltene Danke: 14



BeitragVerfasst: So 13.02.11 17:19 
Edit: Sry, Denkfehler

Für diesen Beitrag haben gedankt: bfelix
bfelix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61

WIN 2000 Prof., Win XP Prof., Win 7 Starter und Prof., SuSe Linux 11.3,
Delphi 7 Pers.
BeitragVerfasst: 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
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 13.02.11 22:03 
Schon mal auf die Idee gekommen, dass er die Datei nicht findet:
ausblenden Delphi-Quelltext
1:
AssignFile(datei, 'ereignisse.med');					

Für diesen Beitrag haben gedankt: bfelix
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 13.02.11 23:04 
Auf die Idee gekommen wohl schon, aber...
user profile iconbfelix hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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:

Für diesen Beitrag haben gedankt: bfelix
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: 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.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.

Für diesen Beitrag haben gedankt: bfelix
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 14.02.11 09:33 
user profile iconbfelix hat folgendes geschrieben Zum zitierten Posting springen:
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.

Für diesen Beitrag haben gedankt: bfelix
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 14.02.11 09:54 
user profile iconjasocul hat folgendes geschrieben Zum zitierten Posting springen:
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).

Für diesen Beitrag haben gedankt: bfelix
bfelix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61

WIN 2000 Prof., Win XP Prof., Win 7 Starter und Prof., SuSe Linux 11.3,
Delphi 7 Pers.
BeitragVerfasst: Mo 14.02.11 22:13 
Weiß jemand, wo ich diesen Compilerschalter finde oder kann mir jemand sagen, was das ist?
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 14.02.11 23:54 
docwiki.embarcadero....r-Direktiven_-_Index
Gleich der erste Eintrag sollte der Richtige sein.

Für diesen Beitrag haben gedankt: bfelix
bfelix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 61

WIN 2000 Prof., Win XP Prof., Win 7 Starter und Prof., SuSe Linux 11.3,
Delphi 7 Pers.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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...