![]() |
INI File Schreiben und auslesen
Liebes Forum,
als Neuling mit Delphi versuche ich es bei Euch um eine Antwort zu bekommen was ich falsch mache. Ich möchte in eine INI Datei die letzte Eingestellte Sprache eintragen und weis leider beim besten willen nicht wie ich das gebacken kriege. Ich habe dsa TUT bem Delphi-Treff genommen und adaptiert. Ich habe auch dort schon einen Beitrag um Hilfe geschrieben. Leider aber nicht die Hilfe bekommen die ich mir erhoffte. Ich habe folgenden Code geschrieben um die INI Datei zu schreiben:
Delphi-Quellcode:
und den Code um die Sprache wieder zum auslesen:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
const Sektion='language'; Eintrag='last language'; var ini: TIniFile; filename: String; begin SiLang1.Language := ComboBox1.Items.Strings[ ComboBox1.ItemIndex ]; filename := ExtractFilePath(ParamStr(0)) + './ini/einstellungen.ini'; //??? ini := TIniFile.Create(filename); try ini.WriteString(Sektion,Eintrag,ComboBox1.Text); finally Ini.Free; end;
Delphi-Quellcode:
Bitte macht mich nicht fertig wenn ich es nicht verstehe, aber bei mir funktioniert es nicht.
procedure TForm1.FormCreate(Sender: TObject);
const Sektion='language'; Eintrag='last language'; var ini: TIniFile; filename: String; begin filename := ExtractFilePath(ParamStr(0)) + './ini/einstellungen.ini'; //??? ini := TIniFile.Create(filename); ComboBox1.Text := Ini.ReadString('Sektion', 'Eintrag', 'Wert'); finally ini.Free; Kann mir jemand von Euch hier aus dem Forum etwas behilflich sein ? Ich wäre sehr dankbar. Herzliche Grüsse aus der Schweiz Chris |
AW: INI File Schreiben und auslesen
Delphi-Quellcode:
filename := ExtractFilePath(ParamStr(0)) + 'ini\einstellungen.ini';
|
AW: INI File Schreiben und auslesen
Vielen Dank Björk,
ok, dann muss ich also doch nicht "./" eingeben. Zitat:
ich denke ich mache im Code:
Delphi-Quellcode:
irgend was falsch.
ComboBox1.Text := Ini.ReadString('Sektion', 'Eintrag', 'Wert');
Es steht nun in der INI Datei "language" als Sektion 1 und in Sektion 2 steht nun der Wert "last language" Und als Wert steht nun Englisch oder Deutsch oder so. Aber wenn ich die Applikation starte steht da immer nur Wert in der Combobox. Leider verstehe ich nicht so viel dass ich mir den Code einfach zusammenbauen kann. eigentlich möchte ich ja schreiben aus Eintrag Sektion1 (Sektion) und Sektion 2 (Eintrag) den Wert, ausgeben in Combobox1.Text. Das steht nun bei mir aber immer "Wert" Danke dass Du Dir für mich Zeit nimmst. Chris |
AW: INI File Schreiben und auslesen
Hallo Chris,
bist du mit Verzecihnis C:\...\ini\ sicher ? BTW: Inifile Format: [Section] Indent = Value Ini.WriteInteger('A','B',1) ergibt: [A] B = 1 |
AW: INI File Schreiben und auslesen
Delphi-Quellcode:
bedeutet, dass du möglicherweise in ein Unterverzeichnis des Programme Ordners schreiben willst, was in der Regel nicht geht, wenn man kein Admin ist.
filename := ExtractFilePath(ParamStr(0)) + 'ini\einstellungen.ini';
Delphi-Quellcode:
bedeutet, dass du den Text der Combobox mit dem Text 'Wert' beschreiben willst. Das soll doch nicht deine Absicht sein.
ComboBox1.Text := Ini.ReadString('Sektion', 'Eintrag', 'Wert');
Du willst doch bestimmt, dass die Comboxbox mehrere Einträge hat und ein Eintrag gewählt wird. Das machst du mit "IndexOf". |
AW: INI File Schreiben und auslesen
Beispiel:
Delphi-Quellcode:
Ini ist eine ganz normale Klasse, sie unterschiedet sich von den meisten vielleicht dadurch, dass man in Create ein Pfad angeben muss. Experimentiere nicht mit dem Pfad, sondern liefere etwas mit Hand und Fuß. Wenn du keine Ahnung hast was für ein Pfad du angibst, dann weißt du auch nicht wo die Ini landet.
uses
IniFiles; procedure TForm1.Button1Click(Sender: TObject); var Path, FileName: String; IniFile: TIniFile; s: String; begin Path := ExtractFilePath(ParamStr(0)); //hat schon ein Backslash am Ende Path := IncludeTrailingPathDelimiter(Path); //braucht man hier nicht, wenn man sich aber unsicher ist, ist es nicht falsch FileName := 'Einstellungen.ini'; //Erstellt falls nötig den Unterordner if not ForceDirectories(Path + 'INI') then begin MessageDlg('Es wurde kein Unterordner angelegt', mtError, [mbOK], 0); Exit; end; //Alternative: Prüft auf Unterordner {if not DirectoryExists(Path + 'INI') then begin MessageDlg('Es wurde kein Unterordner gefunden', mtError, [mbOK], 0); Exit; end; } IniFile := TIniFile.Create(Path + FileName); try IniFile.WriteString('Sektion', 'Ident', 'Wert'); s := IniFile.ReadString('Sektion', 'Ident', 'Ersatzwert bei Fehler'); finally IniFile.Free; end; ShowMessage(s); end; Das sieht nicht gut aus:
Delphi-Quellcode:
ExtractFilePath liefert immer ein Backslash am Ende, also z. B. c:\Temp\Übungen\Projekt1\. Du brauchst also nach ExtractFilePath keinen Backslash angeben (schon gar nicht ein Slash).
ExtractFilePath(ParamStr(0)) + './ini/einstellungen.ini';
Bist du nicht sicher ob am Ende ein Backslash ist, überprüfe es oder verwende die Funktion
Delphi-Quellcode:
. Sie macht nichts kaputt, man kann sie zur Not also immer verwenden. Wenn da bereits ein Backslash am Ende ist, wird nichts gemacht, sonst Backslash angefügt.
IncludeTrailingPathDelimiter
Willst du es in einen Ordner schrieben, dann in der Form:
Delphi-Quellcode:
. Wie gesagt, ExtractFilePath liefert am ende immer einen Backslash.
ExtractFilePath(ParamStr(0)) + 'ini/einstellungen.ini';
Fehlt der Ordner "Ini\", gibt es eine Fehlermeldung. Also vorher vergewissern ob der Ordner existiert. Oder mit
Delphi-Quellcode:
erstellen.
ForceDirectories
Der Rest ist üblich wie bei anderen Klassen: Objekt deklarieren und erstellen, mit Objekt arbeiten, zuletzt IniFile Objekt freigeben. |
AW: INI File Schreiben und auslesen
Das was du in '...' setzt, wird von Delphi auch als String interpretiert. Also hat er in der Ini eine Sektion "Sektion" gesucht, um dort den Eintrag "Eintrag" lesen zu können.
Wenn du die Konstanten (
Delphi-Quellcode:
) verwenden willst, dann darfst du das nicht in '...' setzen.
const Sektion='language'; ...
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
const Sektion='language'; Eintrag='last language'; var ini: TIniFile; filename: String; begin filename := ExtractFilePath(ParamStr(0)) + '\ini\einstellungen.ini'; //??? ini := TIniFile.Create(filename); // ComboBox1.Text := Ini.ReadString('Sektion', 'Eintrag', 'Wert'); ComboBox1.Text := Ini.ReadString(Sektion, Eintrag, 'Standardwert'); finally ini.Free; |
AW: INI File Schreiben und auslesen
Hallo Björk, nuclearping, Popov, und alle die Mit Lesen,
Ja, es ist eigentlich so angedacht, dass ich das Programm frei wählbar Installieren möchte, das bedeutet, dass es überall geladen werden kann so auch die INI Datei, deshalb keinen Direkten Pfad. Ich habe gelesen dass mann über den Parameter:
Delphi-Quellcode:
den Programm Ordner
ExtractFilePath(ParamStr(0))
auslesen kann, und dann soll es einfach ins Verzeichnis INI abgelegt werden. Nun ja, ich möchte nicht nur den Wert aus der Combobox verwenden, den habe ich gefunden in:
Delphi-Quellcode:
sondern ich möchte den Wert aus der INI Datei in die Combobox
ComboBox1.Items
einlesen. Ich habe ein Programm, dass ich Mehrsprachig machen möchte. Grüsse all denen die mir da so tatkräftig Helfen. Chris |
AW: INI File Schreiben und auslesen
Hier noch ein Tipp. Delphi bietet für Ini Nutzer den einfachen Zugriff auf Registry über die TRegIniFile. Die funktioniert genauso wie die TIniFile. Es muss einfach nur die Unit und die Klasse getauscht werden. Der Rest bleibt. Was also bei Ini funktionierte, funktioniert dann auch in der Registry, mit dem Unterschied, dass man nun keine Ini mitschleppten muss.
Delphi-Quellcode:
uses
Registry; //Änderung Registry procedure TForm1.Button2Click(Sender: TObject); var Path: String; IniFile: TRegIniFile; //Änderung TRegIniFile s: String; begin //Dem Pfad sollte 'Software\' vorangestellt sein, damit es richtig im Ordner //für Software abgeleht wird. Dann noch einen Dateinamen. Der Rest wie bei Ini. Path := 'Software\' + 'MeinProgramm'; //Alternativ einfach den Namen der Datei nehmen //Path := 'Software\' + ExtractFileName(ChangeFileExt(ParamStr(0), '')); IniFile := TRegIniFile.Create(Path); //Änderung TRegIniFile try IniFile.WriteString('Sektion', 'Ident', 'Wert'); s := IniFile.ReadString('Sektion', 'Ident', 'Ersatzwert bei Fehler'); finally IniFile.Free; end; ShowMessage(s); end; |
AW: INI File Schreiben und auslesen
|
AW: INI File Schreiben und auslesen
Hallo,
ich gebe Deinen Code jetzt mal in gekürzter Fassung wieder:
Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
const Sektion='language'; Eintrag='last language'; var ini: TIniFile; begin ini := TIniFile.Create(filename); try ini.WriteString(Sektion,Eintrag,ComboBox1.Text); finally Ini.Free; end;
Delphi-Quellcode:
Aua!
procedure TForm1.FormCreate(Sender: TObject);
var ini: TIniFile; begin ini := TIniFile.Create(filename); try ComboBox1.Text := Ini.ReadString('Sektion', 'Eintrag', 'Wert'); finally ini.Free; end end; Dein FormClose schreibt:
Code:
Dein FormCreate ließt (bzw. möchte lesen):
[language]
last language=das was in ComboBox1.Text steht
Code:
Da vermutlich weder der Abschnitt Sektion, noch der Schlüssel Eintrag existiert bzw. dem Schlüssel Eintrag kein Wert zugewiesen ist, steht am Ende der string 'Wert' in ComboBox1.Text drin - und das ist dann schon richtig so.
[Sektion]
Eintrag= Versuche es mal so (das mit dem filename musst Du halt noch ergänzen):
Delphi-Quellcode:
[EDIT]
const
Sektion = 'language'; Eintrag = 'last language'; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var ini: TIniFile; begin ini := TIniFile.Create(filename); try ini.WriteString (Sektion, Eintrag, ComboBox1.Text); finally Ini.Free end; procedure TForm1.FormCreate(Sender: TObject); var ini: TIniFile; begin ini := TIniFile.Create(filename); try ComboBox1.Text := Ini.ReadString (Sektion, Eintrag, 'Default'); finally ini.Free end end; Scheinbar ändert sich filename in Deiner Anforderung nicht; deshalb wäre es sinnvoll, dass Du Dir diese Geschichte nur einmal (FormCreate) zusammenschraubst und anschließend nur noch darauf zugreifst. Also:
Delphi-Quellcode:
[/EDIT]
type
TForm1 = class (TForm) private FIniFileName : string; end; procedure TForm1.CloseForm (Sender : TObject); begin ini := TIniFile.Create (FIniFileName); // Rest wie gehabt end; procedure TForm1.CreateForm (Sender : TObject); begin FIniFileName := ExtractFilePath (ParamStr (0)) + 'ini\einstellungen.ini'; // Rest wie gehabt end; Gruß |
AW: INI File Schreiben und auslesen
Hallo Perlsau,
Zitat:
Darf man etwas anständige Antworten erwarten wenn man nicht mehr weiter weis ? Gruss Chris |
AW: INI File Schreiben und auslesen
Hallo Volker Z.,
ein Dankeschön dass Du Dir Zeit nimmst für mein Problem. In der INI Steht nun: [language] last language=Französisch Ich verstehe nun das nicht, wie der Eintrag "Französisch" wieder in die Combobox zurück kommt. Ich habe nun also genau den Wert den ich brauche. Nur das mit dem Auslesen verstehe ich nicht. Herzlichen Dank allen die da mir das ganze näher Bringen. Chris Zitat:
|
AW: INI File Schreiben und auslesen
Hallo,
nochmal: Beim Schreiben der Daten in die INI nutzt Du die Konstante
Delphi-Quellcode:
; Du legst also im Abschnitt 'language' den Schlüssel 'last language' an und hinterlegst dort einen bestimmten Wert ('Französisch'). Soweit passt alles.
Sektion='language';
Beim Lesen aus der INI greifst Du aber auf den Abschnitt 'Sektion' zu - und eben nicht auf 'language'. Oder: Du liest etwas, was gar nicht 'da' ist. Ein
Delphi-Quellcode:
würde funktionieren, ein
ComboBox1.Text := Ini.ReadString ('language', 'last language', 'Default');
Delphi-Quellcode:
wird es nicht tun.
ComboBox1.Text := Ini.ReadString ('Sektion', 'Eintrag', 'Wert');
Deshalb: Nimm die Konstanten aus
Delphi-Quellcode:
und
FormClose
Delphi-Quellcode:
raus, definiere Dir die Dinger "global" und greife beim Lesen/Schreiben auf diese Konstanten zu.
FormCreate
Groschen nun gefallen? Gruß |
AW: INI File Schreiben und auslesen
Klein wenig übertrieben der Code, aber es soll ja ein Beispiel sein:
Delphi-Quellcode:
uses
IniFiles; const LangList = 'Deutsch, Englisch, Französisch, Spanisch'; //Mit Komma getrennte Liste IniLangSection = 'Sprachen'; IniLangList = 'ListeSprachen'; IniCurLang = 'AktuelleSprache'; function GetIniPath(var IniPath: String): Boolean; const IniSubFolder = 'Ini\'; IniFileName = 'Einstellungen.ini'; var Path: String; begin Path := ExtractFilePath(ParamStr(0)); IniPath := Path + IniSubFolder + IniFileName; Result := ForceDirectories(Path + IniSubFolder); if not Result then MessageDlg('Fehler. Es konnte kein Ini Ordner angelegt werden.', mtError, [mbOK], 0); end; procedure LoadFromIni(ComboBox: TComboBox); var IniFile: TIniFile; IniPath: String; s: String; k: Integer; begin if not GetIniPath(IniPath) then Exit; IniFile := TIniFile.Create(IniPath); try s := IniFile.ReadString(IniLangSection, IniLangList, LangList); ComboBox.Items.CommaText := s; k := IniFile.ReadInteger(IniLangSection, IniCurLang, 0); if (k > -1) and (k < ComboBox.Items.Count) then ComboBox.ItemIndex := k; finally IniFile.Free; end; end; procedure SaveToIni(ComboBox: TComboBox); var IniFile: TIniFile; IniPath: String; s: String; begin if not GetIniPath(IniPath) then Exit; IniFile := TIniFile.Create(IniPath); try IniFile.WriteString(IniLangSection, IniLangList, ComboBox.Items.CommaText); IniFile.WriteInteger(IniLangSection, IniCurLang, ComboBox.ItemIndex); finally IniFile.Free; end; end; procedure AddLanguage(ComboBox: TComboBox; Name: String); begin ComboBox.Items.Add(Name); end; procedure TForm1.ButtonLoadClick(Sender: TObject); begin LoadFromIni(ComboBox1); end; procedure TForm1.ButtonSaveClick(Sender: TObject); begin SaveToIni(ComboBox1); end; procedure TForm1.ButtonAddClick(Sender: TObject); var s: String; begin s := InputBox('Sprache', 'Neue Sprache hinzufügen', ''); if Trim(s) <> '' then AddLanguage(ComboBox1, s); end; |
AW: INI File Schreiben und auslesen
Würde das eher mit einem Aufzählungstypen und über die Eigenschaft ItemIndex machen?
Delphi-Quellcode:
unit MyUnit;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IniFiles; type TLanguage = (lgGerman, lgFrench, lgEnglich, lgSwissGerman); const cLanguage: array [TLanguage] of string = ('Deutsch', 'Französisch', 'Englisch', 'Schweizerdeutsch'); type TMyForm = class(TForm) LanguageComboBox: TComboBox; procedure FormCreate(Sender: TObject); procedure LanguageComboBoxClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private procedure SetLanguageComboBoxItems; end; var MyForm: TMyForm; implementation {$R *.dfm} var Language: TLanguage; function LanguageRange(Value: integer): boolean; var A, B: integer; begin A := Integer(Low(TLanguage)); B := Integer(High(TLanguage)); Result := (Value >= A) and (Value <= B); end; function IntToLanguage(Value: integer): TLanguage; begin if LanguageRange(Value) then Result := TLanguage(Value) else raise Exception.Create('IntToLanguage: Invalid Paramter'); end; function LanguageToInt(Value: TLanguage): integer; begin Result := Integer(Value); end; function IniFileName: string; var Path: string; begin Path := ExtractFilePath(ParamStr(0)) + 'ini\'; if not DirectoryExists(Path) then if not CreateDir(Path) then raise Exception.Create(Format('Cannot create folder %s', [Path])); Result := Path + 'Einstellungen.ini'; end; function LoadLanguageFromIniFile: TLanguage; var Ini: TMemIniFile; begin Ini := TMemIniFile.Create(IniFileName); try Result := IntToLanguage(Ini.ReadInteger('Language', 'Last Language', 0)); finally Ini.Free; end; end; procedure SaveLanguageToIniFile(Language: TLanguage); var Ini: TMemIniFile; begin Ini := TMemIniFile.Create(IniFileName); try Ini.WriteInteger('Language', 'Last Language', LanguageToInt(Language)); finally Ini.UpdateFile; Ini.Free; end; end; procedure TMyForm.LanguageComboBoxClick(Sender: TObject); begin if LanguageRange(LanguageComboBox.ItemIndex) then Language := IntToLanguage(LanguageComboBox.ItemIndex); end; procedure TMyForm.SetLanguageComboBoxItems; var I: TLanguage; begin LanguageComboBox.Items.Clear; LanguageComboBox.Style := csDropDownList; for I := Low(I) to High(I) do // oder for I := lgGerman to lgSwissGerman do LanguageComboBox.Items.Add(cLanguage[I]); end; procedure TMyForm.FormCreate(Sender: TObject); begin SetLanguageComboBoxItems; Language := LoadLanguageFromIniFile; LanguageComboBox.ItemIndex := LanguageToInt(Language); ShowMessage(cLanguage[Language]); end; procedure TMyForm.FormDestroy(Sender: TObject); begin SaveLanguageToIniFile(Language); end; procedure DoSomething; begin if Language = lgEnglich then ShowMessage('I like Englich'); end; procedure DoSomethingElse; begin case Language of lgGerman: begin end; lgFrench: begin end; lgEnglich: begin end; lgSwissGerman: begin end; end; end; end. |
AW: INI File Schreiben und auslesen
@Popov
Hier würden sich Exceptions besser machen, denn nun gibt es auch einen Hinweis, warum der nicht erstellt werden konnte
Delphi-Quellcode:
function GetIniPath : string;
const IniSubFolder = 'Ini\'; IniFileName = 'Einstellungen.ini'; var Path: String; begin Path := ExtractFilePath(ParamStr(0)); Result := Path + IniSubFolder + IniFileName; if not ForceDirectories( Path + IniSubFolder ) then RaiseLastOSError; end; procedure LoadFromIni(ComboBox: TComboBox); var IniFile: TIniFile; s: String; k: Integer; begin IniFile := TIniFile.Create( GetIniPath ); try s := IniFile.ReadString(IniLangSection, IniLangList, LangList); ComboBox.Items.CommaText := s; k := IniFile.ReadInteger(IniLangSection, IniCurLang, 0); if (k > -1) and (k < ComboBox.Items.Count) then ComboBox.ItemIndex := k; finally IniFile.Free; end; end; procedure SaveToIni(ComboBox: TComboBox); var IniFile: TIniFile; s: String; begin IniFile := TIniFile.Create( GetIniPath ); try IniFile.WriteString(IniLangSection, IniLangList, ComboBox.Items.CommaText); IniFile.WriteInteger(IniLangSection, IniCurLang, ComboBox.ItemIndex); finally IniFile.Free; end; end; |
AW: INI File Schreiben und auslesen
Ich würde die INI nicht ins Programmverzeichnis "ExtractFilePath(ParamStr(0))" packen, sondern ein passendes Verzeichnis dafür nehmen Stichwort: .
![]() ![]() |
AW: INI File Schreiben und auslesen
Hallo Volker Z.,
leider übersteigt das ganze mein Verständnis, nein, ich habs nicht so ganz verstanden. Dass ich es lieber Global mache verstehe ich noch, aber wesshalb dann statt "Eintrag" direkt "language" setzen verstehe ich noch nicht so ganz. Und wesshalb übernimmt er mir den Wert nicht aus der INI ? In der INI Stehts ja. Ich habe nochmals gelesen im TUT,
Delphi-Quellcode:
"Kein Wert" ist ja ein direkter Eintrag und nicht der Wert aus der INI oder verstehe ich das Falsch ?
Edit1.Text:=Ini.ReadString('Section', 'Schlüssel1', 'kein Wert');
Was muss ich dann einfügen bei "Wert" resp. "kein Wert" dass es klappt ? Muss ich doch noch eine Const. für "Wert" hinterlegen ? Aber ich habe leider völligen Bahnhof. Sorry für meine lange Leitung. Chris Zitat:
|
AW: INI File Schreiben und auslesen
@floppybe
Wenn du dem Nachbarn Meier (Ident) im Haus zu deiner Linken (Sektion) einen Apfel gibts (Value)
Delphi-Quellcode:
und dann den Nachbarn Müller (Ident) im Haus zu deiner Rechten (Sektion) fragst, was du ihm gegeben hast
begin
Ini.WriteString( 'HausLinks', 'Meier', 'Apfel' ); end;
Delphi-Quellcode:
erwartest du dann den Apfel (Value)?
if Ini.ReadString( 'HausRechts', 'Müller', 'normal nix' ) = 'Apfel' then
ShowMessage( 'Juhu, Apfel essen :-)' ) else ShowMessage( 'In die Röhre schauen :-(' ); Nö, du musst schon genau den fragen, dem du den Apfel gegeben hast
Delphi-Quellcode:
Es ist auch immer hilfreich sich die Dokumentation durchzulesen (anschauen reicht nicht)
if Ini.ReadString( 'HausLinks', 'Meier', 'normal nix' ) = 'Apfel' then
ShowMessage( 'Juhu, Apfel essen :-)' ) else ShowMessage( 'In die Röhre schauen :-(' ); ![]() ![]() dann siehst du auch, wann bei
Delphi-Quellcode:
der Default-Wert zurückgeliefert wird.
ReadString
|
AW: INI File Schreiben und auslesen
Bei
Edit1.Text:=Ini.ReadString('Section', 'Schlüssel1', 'kein Wert'); ist "kein Wert" sowas wie der Default-Wert, den die Funktion nimmt, wenn Sie nix anderes fidnet. Könntest du dann so machen: Edit1.Text:=Ini.ReadString('Section', 'Schlüssel1', 'Deutsch'); oder wenn Edit1.Text schon beim Start Standardmäßig auf Deutsch steht dann: Edit1.Text:=Ini.ReadString('Section', 'Schlüssel1', Edit1.Text); Das entscheidende, was dir aber alle sagen wollen ist, dass das bei dir nicht Section und Schlüssel1 heißt sondern language und last language, somit: Edit1.Text:=Ini.ReadString('language', 'last language', Edit1.Text); oder halt mit Variablen:
Delphi-Quellcode:
var Sektion,Eintrag:String;
... Sektion:='language'; Eintrag:='last language'; ... Edit1.Text:=Ini.ReadString(Sektion, Eintrag, Edit1.Text); |
AW: INI File Schreiben und auslesen
@floppybe
Nochmal zum Aufbau einer Ini-Datei
Code:
Wie du siehst ist die Ini in Sektionen unterteilt. Dadurch ist es möglich drei Mal den Ident mit dem gleichen Namen "Ident1" zu verwenden, ohne dass es zu Komplikationen kommt. Ohne Sektionen müsste man für jeden Ident einen anderen Namen nehmen.
[Sektion1]
Itent1=Value1 Ident2=Value2 Ident3=Value3 [Sektion2] Itent1=Value1 Ident2=Value2 Ident3=Value3 [SektionN] Itent1=Value1 Ident2=Value2 Ident3=Value3 Nun keine Gesetze, aber Regeln die das Leben erleichtern: Es empfiehlt sich die Namen für Sektionen und Idents als Konstanten global zu nutzen. Grund: man kann sich immer leicht verschreiben. Ohne Konstanten fällt der Fehler nicht auf
Delphi-Quellcode:
. Hier fällt dem Compiler nicht auf, dass in 'AktueleSprache' ein L fehlt. Wenn man bei
IniFile.ReadInteger('Sprachen', 'AktueleSprache', 0);
Delphi-Quellcode:
ein Fehler macht, fällt es auf, dass "IniCurrLang" mit zwei R geschrieben wurde, denn IniCurLang ist eine Konstante.
IniFile.ReadInteger(IniLangSection, IniCurrLang, 0);
Das Gleiche gilt für den IniPfad. Wer den Pfad immer wieder aufs neue zusammensetzt, dem unterläuft garantiert irgendwann ein Fehler. Am besten den Namen übe reine Funktion holen. Nun zu deiner Frage:
Code:
'kein Wert' ist ein Defaultwert bei Read Methoden und kommt immer dann zum Einsatz wenn ein Fehler vorliegt. Ein Fehler kann immer dann vorliegen, wenn es z. B. keinen Eintrag gibt. Entweder fehlt die Sektion oder Ident, so dass an der Stelle keine Information vorliegt. Statt aber mit einer Fehlermeldung abzubrechen, wird ersatzweise der Defautwert genommen, in dem Fall 'kein Wert'. Ein weitere Grund für einen Fehler kann sein, dass zwar alles da ist, also Sektion und Ident, aber man einen Integer laden will und die Funktion erkennt, dass in der Ini als Wert ein String vorliegt (Selbst wenn es "1.0" ist).
Ich habe nochmals gelesen im TUT, Edit1.Text:=Ini.ReadString('Section', 'Schlüssel1', 'kein Wert'); "Kein Wert" ist ja ein direkter Eintrag und nicht der Wert aus der INI oder verstehe ich das Falsch ?
Der Defaultwert ist also der Ersatz-Wert im Fall, dass ein Fehler vorkommt und der Wert nicht korrekt gelesen werden kann. |
AW: INI File Schreiben und auslesen
Zitat:
Delphi-Quellcode:
nehmen können. In dem Fall könnte man auch ein String als Ergebnis liefern und dennoch eine eigene Fehlermeldung verfassen.
raise Exception.Create('Fehler. Es konnte kein Ini Ordner angelegt werden.');
|
AW: INI File Schreiben und auslesen
Zitat:
Delphi-Quellcode:
if not ForceDirectories( Dir ) then
RaiseLastOSError( GetLastError, Format(' "%s"', [Dir] ) ); Zitat:
Zitat:
![]() |
AW: INI File Schreiben und auslesen
Zitat:
Außerdem, was interessiert den Endnutzer, oder gar den TE der ErrorCode 5. Das ist fast so gut wie die Frage nach dem Sinn des Lebens mit der Antwort 42. Es sollte also immer ein Text da stehen. Wo wir aber dabei sind, ich kenne die Schreibweise
Delphi-Quellcode:
nicht, ist das neu > D7?
RaiseLastOSError( GetLastError, Format(' "%s"', [Dir] ) );
|
AW: INI File Schreiben und auslesen
Zitat:
Und dann verbleibt der Schrott von allen möglichen Programmen auch noch da... Man kann also durchaus geteilter Meinung über den Vorteil von INI-Dateien sein. Zitat:
"Default" ist das was rauskommt wenn die INI aus welchen Gründen auch immer nichts liefert. Gruß K-H |
AW: INI File Schreiben und auslesen
Zitat:
Natürlich hat die Ini seinen Vorteil, der Nachteil ist aber, dass man sie nicht überall speichern kann. Die Alternative mit dem Anwendungsdaten-Ordner ist ok, das Problem ist, dass man sich vorher immer erst verrenken muss um den Ordner zu finden. Selbst wenn man den Ordner nicht mit der Spezial-Ordner-Funktion sucht und die Umgebungsvariablen nutzt, es muss immer erst nachgeguckt werden wie der Code so ist.
Delphi-Quellcode:
Kürzer geht es nicht, in der Regel ist der Code komplizierter, aber heute ist so ein schöner Tag, deshalb habe ich es einfach gehalten. Die dritte Alternative ist einfach die TIniFile gegen die TRegIniFile tauschen, und schon sind alle Probleme vergessen ;)
var
Str: array [0..1023] of Char; Len: Integer; begin Len := ExpandEnvironmentStrings(PChar('%APPDATA%'), Str, 1024); |
AW: INI File Schreiben und auslesen
Zitat:
Zitat:
Übrigens habe ich nichts gegen die Registry, die Idee ist gut, die Umsetzung allerdings teilweise grausam. Gruß K-H |
AW: INI File Schreiben und auslesen
Jupp. Neue Programme entwickle ich erstmal "portable" mit INIs mittels globalem
Delphi-Quellcode:
im FormCreate. :oops:
INIFileName := ChangeFileExt(paramstr(0), '.ini');
|
AW: INI File Schreiben und auslesen
Würde ich nicht machen. Besser dafür ist eine Funktion geeignet, auch wenn sie als Result den gleichen Wert liefert. Man hat dann immer die Möglichkeit den Pfad anzupassen.
|
AW: INI File Schreiben und auslesen
Zitat:
|
AW: INI File Schreiben und auslesen
Hallo Jumpy und Popov,
jetzt wird es mir auch wieder etwas klarer mit der INI. OK. Ich mache es mal Global und versuche den Test wieder auszulesen. Ich erlaube mir das Resultat hier wieder zu Präsentieren. Habt vielen Dank für Alle Eure Ausführungen. Chris |
AW: INI File Schreiben und auslesen
Ich hatte es im DT schon angedeutet, trotzdem scheint es trotz mehrfacher Hinweise auch in diesem Thread immer noch nicht angekommen zu sein. Was wird in diesem Testcode jeweils ausgegeben?
Delphi-Quellcode:
Wenn man das weiß, muss man sich nur das Schreiben und Lesen noch einmal ganz genau anschauen.
const
Blubb = 'Hallo Welt'; begin ShowMessage('Blubb'); ShowMessage(Blubb); |
AW: INI File Schreiben und auslesen
Hallo Guten Abend,
ich habe den Code vom Einlesen der INI so umgeschrieben dass ich statt der Const direkt den "Wert" genommen habe.
Delphi-Quellcode:
Wenn ich "language" und "last language" nehme gehts. Ich verstehe das noch nicht so ganz,
filename := ExtractFilePath(ParamStr(0)) + 'ini/einstellungen.ini'; //???
ini := TIniFile.Create(filename); silang1.Language := Ini.ReadString('language', 'last language', 'Deutsch' ); binn aber froh dass ich nun weiter gekommen bin. Danke an alle welche geholfen haben bei der Lösung. Chris |
AW: INI File Schreiben und auslesen
Man merkt, dass du gegen gute Tipps schon klein wenig abgeneigt bist. Es ist nun mal so, dass es die typischen Fehler gibt. Anscheinend möchtest du die selbst erleben. Kann man aber auch gut verstehen - no Risk, no Fun ;)
Du verstehst nicht was da passiert? Dabei ist das Ganze eigentlich nicht so schwer. Aber vielleicht sollte man nicht alles auf einmal durchnehmen. Wenn du Lust hast, können wir es noch mal in kleinen Schritten durchgehen: silang1.Language := Ini.ReadString('language', 'last language', 'Deutsch' ); Was sagt dieser Parameter aus. Welchen Teil der Ini repräsentiert er? |
AW: INI File Schreiben und auslesen
Hallo Popov,
vielen Hertzlichen Dank dass Du Dir Zeit nimmst mir das ganze etwas besser zu Erklähren. Ich nehme das Angebot gerne an. Language ist der Einstig der Werte Wo die Daten abgelegt sind, denke ich. Wenn ich also "Sektion" nehmen würde sucht er mir nach Sektion und nicht nach Language. Wenn ich das Richtig verstehe. Ich bin es mir gewohnt immer noch den Code selber zusammen zu basteln, als dass ich fertige Infos bekomme. Was ich sehr Gut verstehen kann aber bei mir manchmal eben zu verwirrungen führt. Ich bin froh, einen Code zu bekommen den mann verstehen kann. Ich habe einfach bei Euren Ausführungen falsch gelesen und miss verstanden. Gruss Chris Zitat:
|
AW: INI File Schreiben und auslesen
Gut, ich hab die Frage missverständlich gestellt, ist aber nicht schlimm.
silang1.Language := Ini.ReadString('language', 'last language', 'Deutsch' ); Eigentlich wollte ich wissen, in welchem Teil der Ini er sucht. Man muss sich zuerst über den Aufbau der Ini im klaren sein, man muss sich bewusst sein, dass es bei der Ini drei Schritte bis zu gesuchten Info gibt - zuerst muss man die Ini-Datei wählen, dann muss man innerhalb der Ini den Teilbereich (Section) wählen, zuletzt muss man den Schlüssel (Ident) wählen:
Code:
Man kann übrigens auch eine normale Textdatei nehmen, sie über TStringLIst laden und Werte über Schlüssel suchen. Das kann jede StringList, sie kennt nur keine Sektionen. Das würde dann so aussehen:
IniFile
| +-Section1 | | | +-Ident1 = Value | +-Ident2 = Value | +-Ident3 = Value | +-Section2 | | | +-Ident1 = Value | +-Ident4 = Value | +-Ident5 = Value | +-Section3
Code:
Die StrlingList hat dann also eine Liste in der Form:
TxtFile
| +-Name1 = Value +-Name2 = Value +-Name3 = Value +-Name4 = Value +-Name5 = Value +-Name6 = Value
Code:
Man kann hier also genauso an die Daten kommen wie bei einer Ini. Was ist aber der Unterschied? Die StringList kennt keine Unterteilung innerhalb der Liste. In der ganzen Liste müssen alle Schlüssel (also Ident oder Names) stets einmalig sein, sonst werden sie nicht gefunden. Auf den Wert in Zeile 3 kommt man bei einer StringList nie dran - Grund: sie benutzt als Schlussel die Bezeichnung "Info1", und das taucht in der Liste in der ersten Zeile bereits auf. Die dritte Zeile kann also nicht angesprochen werden.
Info1 = Wert A
Info2 = Wert B Info1 = Wert C Hier schlaft die Ini-Datei Abhilfe, denn sie kann die Datei noch ein weiteres Mal unterteilen, und zwar in Sektionen.
Code:
Und nun kann man an den Wert drann, man muss aber der Funktion zum auslesen der Info sagen an welche Info1 in der Liste will man. In welcher Sektion befindet es sich. Also schriebt man:
[Sektion1]
Info1 = Wert A Info2 = Wert B [Sektion2] Info1 = Wert C
Delphi-Quellcode:
Sektion unterteilt also die eine große Ini Liste mit Werten in kleine Teillisten, geordnet nach Themen
xyz := Ini.ReadString('Sektion2', 'Info1 ', 'Erstzwert');
//
Delphi-Quellcode:
Man kann sich die Sektion auch als Ordner vorstellen und die Idents als Blätter mit Infos. In einen Ordner kann man viel Blätter legen. In einen weiteren Ordner kann man andere Blätter legen.
silang1.Language := Ini.ReadString('language', 'last language', 'Deutsch' );
// |
AW: INI File Schreiben und auslesen
Hallo Popov,
ich glaube langsam verstehe ich den Bereich INI auch etwas besser. Bei der TXT Datei statt der INI würde man also Nur Language wählen, oder last language aber nicht beides. Dass ich aber das ganze auch über eine TXT Datei fürhren könnte wusste ich nun auch nicht. Ist aber eigentlich Logisch. Beides sind Text Dateien. Beide sollten ähnlich lesbar sein. Chris |
AW: INI File Schreiben und auslesen
Du solltest verstehen:
Code:
Mit jedem Schritt weiter in die Tiefe wird es immer konkreter und damit spezieller.
Datei->Textdatei->INI-Datei
Code:
<Datei>
Pfad Name Erweiterung Größe (in Bytes)
Code:
<Textdatei>(<Datei>)
Kodierung (ASCII, ANSI, UTF8, ...) Zeilenende (CR, LF, CRLF, ...) ZeilenAnzahl ZeichenAnzahl |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:05 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz