Entwickler-Ecke

Dateizugriff - Record


Apo95 - Mi 09.04.14 00:42
Titel: Record
Hallo, ich habe folgenden Quellcode, sehe aber den Fehler (E/A-Fehler 103) nicht, bzw. die Ursache :

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:
//gonis-projektdatei definieren
type
TGonisFile = record
ver : string[8];
desc : string[18];
thema : string[100];
index : integer;
benutzername : string[100];
suchbegriff1 : string[100];
suchbegriff2 : string[100];
suchbegriff3 : string[100];
//commentar : LongWord;
end;

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
  function ExpandEnvStr(const szInput: string): string;
var
  Form3: TForm3;
  cStore : string;
  projname : String;
  sl : TStringList;
  cd : String;
  i,nModul : integer;         //Für ProgressBar
//  Parent, Node: ttreenode; 
implementation

uses thema;

{$R *.dfm}

procedure TForm3.SpeedButton1Click(Sender: TObject);
var
datei : file of TGonisFile;
gonfile : string;
begin
cStore := ExpandEnvStr(Edit1.text+Edit2.text);
ProgressBar1.Visible := true;

     if (Edit1.Text = ''or (Edit2.Text = ''then
     begin
       Application.MessageBox('Geben Sie einen Projektnamen ein.',
       '',MB_ICONINFORMATION);
     end else
         begin
           //Verzeichnis erzeugen
           ForceDirectories(Edit1.Text+'\'+ProjName);
           //Datei *.tas erzeugen ===> Text
           sl := TStringList.Create;
           try
             sl.add('Project successfully created : '+Edit1.Text+'\'+Edit2.Text);
             sl.savetofile(Edit1.text+'\'+Edit2.Text+'.tas');

                    AssignFile(datei,cstore+Edit1.text+'.gon');
                  //  reset(datei);
                   // Rewrite(datei);
                    write(gonfile);
           finally
             sl.free;
             CloseFile(datei);
       ForceDirectories(Edit1.Text+'\'+Edit2.Text);
             Application.MessageBox('Projekt wurde erfolgreich erzeugt.',
             '',MB_ICONINFORMATION);
             close
           end;
             //frm_topic.treeview1.add;
           //Node := frm_topic.TreeView1.Items.AddChildFirst(nil, Edit2.Text);
         end;


Wo ist die Ursache??? Ich vermute, dass die Datei (GON-Datei) gleichzeitig erzeugt und geschlossen wird, das glaube ich bedeutet der Fehler... :?!?:


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 09.04.2014 um 10:45


MeierZwoo - Mi 09.04.14 03:08

Nach dem AssignFile muß die Datei auch geöffnet werden!
I/O-Fehler 103: "Datei nicht geöffnet".
Die Öffnungs-Procedure (reset bzw. rewrite) ist bei Dir auskommentiert!

Normaleweise öffnet man die Datei mit (Zeile 2..4):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  ...
  AssignFile(datei,cstore+Edit1.text+'.gon');
  {$I-} reset(datei}; {$I+}            // ist datei vorh., ist IOResult=0
  if IOResult<>0 then rewrite(datei);  // nicht vorh. ist IOResult<>0, dann datei neu anlegen
  ...
                         // ab hier geht auch so ziemlich alles durcheinander:
  write(datei,gonfile);  // write muß das Ziel (die Dateivar) und den Datensatz enthalten,
                         // hier ist auch noch ein falscher Datensatz angegeben, ein string
                         // statt ein Datensatz vom type TGonisFile. dem type der Datei.
  ...                    // Ohne Ziel schreibt write an StdOut (Bildschirm)   
  {$I-} CloseFile(datei); {$I+} if IOResult<>0 then;
  ...


Dazu muß auch gesagt werden, einen Datensatz "gonfile : string;" oder
"type TGonisFile = record ..." zu benennen, ist schon etwas unglücklich,
genau wie eine Dateivariable mit "datei" zu benennen.


Delete - Mi 09.04.14 11:46

In deinem Code ist nirgendwo zu erkennen, welche Variable denn nun den eigentlichen Record vom Typ TGonisFile enthält. Mit anderen Worten: Bislang hattest du nur den Typen deklariert, jedoch keine Variable dieses Typs angelegt. Solltest du z.B. beabsichtigen, mehrere gleichartige "Items" deines Records zu verwenden, böte es sich an, dafür ein Array zu einzusetzen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  private { Private-Deklarationen }
    MaxData        = 100;
    Data_Dateiname = '';
    MeineDaten   : Array[1..MaxData] of TGonisFile;
    Data_Anzahl,
    Data_Aktuell : Integer;
    Data_Pfad    : String;
    Gesichert    : Boolean;

    Procedure Speichern;
    Procedure Laden;


Beim Sichern des Records auf Platte speicherst du dann die bereits gefüllte Anzahl an Records (die du in der Variablen Data_Anzahl immer aktuell hältst):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Procecure TForm3.Speichern;
Var
  f : File of TGonisFile;
  i : Integer;

Begin
  AssignFile(Data_Pfad + Data_Dateiname);
  Rewrite(f);
  For i := 1 to Data_Anzahl DO
    Write(f, MeineDaten[i]);
 
  CloseFile(f);
  Gesichert := True;
End;

Analog dazu lädst du die gespeicherten Records ebenfalls in einer privaten Procedure wieder ein:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
Procecure TForm3.Laden;
Var
  f : File of TGonisFile;
  i : Integer;

Begin
  AssignFile(Data_Pfad + Data_Dateiname);
  Reset(f);
  i := 0;

  While not Eof(f) DO
  Begin
    Inc(i);
    Read(f, MeineDaten[i]);
  End;
  
  CloseFile(f);
  Gesichert := True;
  Data_Anzahl := i;
  If Data_Anzahl >  0 Then Data_Aktuell := 1;
End;


Diese beiden Proceduren kannst du nun aus deinen ButtonKlickEreignisBehandlungen heraus aufrufen. Der Übersicht halber und auch programmtechnisch ist es nämlich immer günstiger, solche Methoden privat zu deklarieren und implementieren. So kannst du später leicht auch auf Menüsteuerung (Speichern und Laden aus dem Menü heraus statt via Buttons aufrufen) umsteigen, ohne große Herumkopiererei dieser Methoden.