Autor |
Beitrag |
bf109g.01
      
Beiträge: 84
|
Verfasst: Mi 23.03.11 00:18
Hallo, ich benutze für mein Programm eine INI-Datei.
Nun habe ich folgendes Problem.
- Beim Programmstart soll die INI ausgelesen werden.
- Ist keine vorhanden, soll eine erzeugt, mit Standardwerten beschrieben und abgespeichert werden.
- Die Datei wird zwar erzeugt, ist danach aber immer leer. Erst wenn man das gesamte Programm neustartet, funktioniert das GAnze.
Was muss ich da jetzt bitte ändern?
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:
| type Spieler= record Name : string[15]; color: Tcolor; Games: Integer; end; Speicherfeld=array [1..3] of Spieler; var Speicher : Speicherfeld; Player1, Player2, AllgPlayer: Spieler; procedure TForm_Spiel.StartDaten_einlesen; var Save: File of Speicherfeld; path: string; begin path:=ExtractFilePath(ParamStr(0))+'\config.ini'; if not fileexists(path) then begin Filecreate('config.ini'); MessageDlg('File "config.ini" can not be found.', mtError, [mbok], 0); Standardsettings; Spiel_Speichern; end else begin AssignFile(Save,Path); Reset(Save); read(Save,Speicher); CloseFile(Save);
Player1:=Speicher[1]; Player2:=Speicher[2]; AllgPlayer:=Speicher[3]; end;
En1.Text:=Player1.name; En2.Text:=Player2.name; Pf1.color:=Player1.color; Pf2.color:=Player2.color; end;
procedure TForm_Spiel.Standardsettings; begin Player1.name:='Player 1'; Player1.color:=clred; Player2.name:='Player 2'; Player2.color:=clblue; AllgPlayer.Games:=0; end;
procedure TForm_Spiel.Spiel_Speichern; var Save: File of Speicherfeld; path: string; begin Speicher[1]:=Player1; Speicher[2]:=Player2; Speicher[3]:=AllgPlayer;
path:=ExtractFilePath(ParamStr(0))+'\config.ini';
AssignFile(Save,path); Rewrite(Save); write(Save,Speicher); CloseFile(Save); end; |
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 23.03.11 01:16
E/A-Fehler 32 = "The process cannot access the file because it is being used by another process." Siehe: msdn.microsoft.com/e...ms681382(VS.85).aspx
So wie ich das sehe, wird nach dem FileCreate die Datei nicht geschlossen. Wenn Du dann versuchst, die Datei nochmals zu öffnen, knallt es.
Warum wertest Du nicht die Rückgabewerte der Funktionen aus?
Auszug aus der Hilfe zu FileClose: "Mit FileClose kann eine Datei anhand ihres Handles geschlossen werden. Sie erhalten das Handle beim Öffnen der Datei mit FileOpen oder FileCreate."
Für diesen Beitrag haben gedankt: bf109g.01
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.03.11 07:13
Du kannst die Hilfe auch einfach verlinken.
docwiki.embarcadero....e/SysUtils.FileClose
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 23.03.11 09:14
Das CreateFile ist überflüssig und die Ursache des Fehlers.
Rewrite sorgt schon dafür, dass die Datei angelegt wird, falls diese nicht existiert.
btw:
Das ist keine INI-Datei, sondern eine typisierte Datei. 
Für diesen Beitrag haben gedankt: bf109g.01
|
|
bf109g.01 
      
Beiträge: 84
|
Verfasst: Mi 23.03.11 18:37
jasocul hat folgendes geschrieben : | btw:
Das ist keine INI-Datei, sondern eine typisierte Datei.  |
Dann wäre es doch auch sehr geistreich, die Datei nicht als *.ini anzulegen, denke ich.
Welchen Typ nimmt man dann standardmäßig stattdessen? *.dat?
Werde jetzt einfach mal das Filecreate rausschmeißen und schauen, was geschieht. 
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.03.11 18:41
bf109g.01 hat folgendes geschrieben : | Welchen Typ nimmt man dann standardmäßig stattdessen? *.dat? |
Die Endung gibt es schon in Windows selbst, ich würde z.B. .gameconfig oder so etwas nehmen.
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 23.03.11 18:48
Zitat: | Dann wäre es doch auch sehr geistreich, die Datei nicht als *.ini anzulegen, denke ich. |
Warum nimmst Du nicht TIniFile (Unit IniFiles)? Wie ich sehe, hast du doch nur Strings und Zahlen zu speichern. Auch Color ist nix anderes als eine Zahl.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.03.11 19:12
Besser ist dann TMemIniFile (wenn schon INIs benutzt werden). Denn TIniFile benutzt die alten Windows API Routinen aus der 16-Bit Zeit vor 20 Jahren (woher ja auch INIs stammen). Die sind erstens als deprecated markiert und dementsprechend vielleicht z.B. in Windows 8 schon nicht mehr da und zweitens musste ich feststellen, dass die auch nicht immer wie gewünscht arbeiten.
TMemIniFile benutzt eigene Implementierungen (zumindest unter Delphi XE) und arbeitet korrekt.
Davon abgesehen würde ich eher XML-Dateien nehmen, zum Beispiel mit meiner entsprechenden Unit, die das alles kapselt:
www.delphi-forum.de/viewtopic.php?t=92348
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 23.03.11 20:22
jaenicke hat folgendes geschrieben : | Besser ist dann TMemIniFile (wenn schon INIs benutzt werden). Denn TIniFile benutzt die alten Windows API Routinen aus der 16-Bit Zeit vor 20 Jahren (woher ja auch INIs stammen). Die sind erstens als deprecated markiert und dementsprechend vielleicht z.B. in Windows 8 schon nicht mehr da und zweitens musste ich feststellen, dass die auch nicht immer wie gewünscht arbeiten. |
Weder in der XE-Hilfe ms-help://embarcadero.rs_xe/vcl/IniFiles.TCustomIniFile.ReadInteger.html noch bei docwiki.embarcadero.....TIniFile.ReadString ist ein entsprechender Hinweis zu finden. Ich arbeite hier problemlos mit IniFiles unter XE und Windows 32. Außerdem hat TMemInifile gegenüber TIniFile den Nachteil, daß die Schreibzugriffe gecached werden.
jaenicke hat folgendes geschrieben : | Davon abgesehen würde ich eher XML-Dateien nehmen |
Ich hasse die Dinger ...
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.03.11 20:37
Dort nicht, aber bei den API-Funktionen, die diese Methoden benutzen. Und wenn die nicht mehr funktionieren irgendwann, funktionieren logischerweise auch alle Programme, die diese Funktionen nutzen, nicht mehr.
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Do 24.03.11 01:04
jaenicke hat folgendes geschrieben : | Dort nicht, aber bei den API-Funktionen, die diese Methoden benutzen. Und wenn die nicht mehr funktionieren irgendwann,[...] |
Bis dahin wird noch sehr viel Wasser den Main hinunter fließen ...
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 24.03.11 06:50
Gerd Kayser hat folgendes geschrieben : | Bis dahin wird noch sehr viel Wasser den Main hinunter fließen ... |
Vermutlich, aber wissen kann man das nicht. Schließlich sind bei 64-Bit Systemen diese Funktionen nicht mehr notwendig, da 16-Bit Programme ohnehin nicht mehr funktionieren. Sobald es also keine 32-Bit Version von Windows mehr gibt, macht es auch keinen Sinn mehr diese Funktionen zu behalten.
Davon abgesehen gibt es schließlich eine Alternative, die nicht auf diesen API Funktionen aufsetzt. Zudem einmal als Beispiel: Quelltext 1: 2:
| [Test] a="Test","Nichts" | Was kommt bei ReadString wohl heraus?
Bei TIniFile: Test","Nichts
Bei TMemIniFile: "Test","Nichts"
Das ist nur eines der Probleme, die TIniFile bei mir bereits gemacht hat...
|
|
|