Entwickler-Ecke

Dateizugriff - Anstand zwischen den Bereichen in INI-Datei


Olli_Sahr - Mo 22.05.06 21:08
Titel: Anstand zwischen den Bereichen in INI-Datei
Liebes Forum,

ich speichere in meiner Anwendung Daten in einer INI Datei.
Das Speichern funktioniert einwandfrei.
Ich mache das folgendermaßen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure SaveIniFile;
var
   tmpIniFile: TIniFile;

begin
   try
      tmpIniFile := TIniFile.Create(ConfigurationFile); 
      // Der Dateiname der INI wird über eine Funktion ermittelt, ist hier nicht relevant

      (** Bereich 1 **) 
      tmpIniFile.WriteString('Bereich_1''Schluessel_1''Wert_1');
      tmpIniFile.WriteString('Bereich_1''Schluessel_2''Wert_2');
      tmpIniFile.WriteString('Bereich_1''Schluessel_3''Wert_3');
      (** Bereich 2 **)
      tmpIniFile.WriteString('Bereich_2''Schluessel_1''Wert_1');
      tmpIniFile.WriteString('Bereich_2''Schluessel_2''Wert_2');
      tmpIniFile.WriteString('Bereich_2''Schluessel_3''Wert_3');
   finally
      tmpIniFile.Free;
   end;
end;


Delphi erstellt dann folgnde INI-Datei:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
[Bereich_1]
Schluessel_1=Wert_1
Schluessel_2=Wert_2
Schluessel_3=Wert_3
[Bereich_2]
Schluessel_1=Wert_1
Schluessel_2=Wert_2
Schluessel_3=Wert_3

Das funktioniert alles bestens und es tritt auch kein Fehler auf.
Was mich an der Sache allerdings stört ist: zwischen dem letzten Eintrag aus dem ersten Bereich und dem zweiten Bereich fehlt eine Leerzeile.
Es soll also so aussehen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
[Bereich_1]
Schluessel_1=Wert_1
Schluessel_2=Wert_2
Schluessel_3=Wert_3

[Bereich_2]
Schluessel_1=Wert_1
Schluessel_2=Wert_2
Schluessel_3=Wert_3

Wie kann ich Delphi dazu bringen in der INI zwischen den einzelnen Bereichen eine Leerzeile zu lassen (also die Zeile 5 im unteren Quelltext einzufügen)?
Ist das überhaupt möglich?
Es würde die Lesbarkeit (gerade bei größeren INI Dateien) enorm erhöhen.

Danke für Eure Hilfe!

Gruß

OLLI


Marco D. - Mo 22.05.06 21:15

Möglicherweise in eine Stringlist laden, nach einer [ suchen und in der Zeile davor eine Leerzeile einfügen. Aber ein bisschen aufwendiger. Dazu würde ich eine eigene Funktion schreiben. Versuche es erstmal alleine ;)


Marco D. - Mo 22.05.06 21:22

Aber sage mal, warum willst du denn diese Leerzeile(n) einfügen. Eigentlich brauchst du doch diese Datei nicht zu öffnen :gruebel:


JayEff - Mo 22.05.06 22:10

Warum auch immer, Es geht schon.
Lade die datei in eine Stringlist und ersetze per StringReplace jedes vorkommen der [ mit #13#10+'[' Das macht vor jede [ eine neue Zeile.


Blackheart666 - Mo 22.05.06 22:21

Der Sinn würde mich auch mal interessieren !?


root_at_localhost - Mo 22.05.06 23:02

Ach denn Sinn sehe ich schon, wenn ich INI-Dateien verwende dann will ich die auch in Notepad lesen können, sonst könnte ich die daten auch in ne Binärdatei tun. Bei größeren Dateien geht das aber nunmal mit ein paar zusätzlichen Leerzeilen besser...

Zum Topic, mein Tipp:

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:
procedure SaveIniFile;
var
   tmpIniFile: TMemIniFile;
   tmpStringList: TStrings;
   i : integer;
begin
   try
      tmpIniFile := TIniFile.Create(ConfigurationFile); 
      // Der Dateiname der INI wird über eine Funktion ermittelt, ist hier nicht relevant
      (** Bereich 1 **) 
      tmpIniFile.WriteString('Bereich_1''Schluessel_1''Wert_1');
      tmpIniFile.WriteString('Bereich_1''Schluessel_2''Wert_2');
      tmpIniFile.WriteString('Bereich_1''Schluessel_3''Wert_3');
      (** Bereich 2 **)
      tmpIniFile.WriteString('Bereich_2''Schluessel_1''Wert_1');
      tmpIniFile.WriteString('Bereich_2''Schluessel_2''Wert_2');
      tmpIniFile.WriteString('Bereich_2''Schluessel_3''Wert_3');

      tmpStringList := TStringList.Create;
      tmpIniFile.GetStrings(tmpStringList);
      for i := tmpStringList.Count - 1 downto 0 do
        if tmpStringList.Strings[i][1] = '[' then
          tmpStringList.Insert(i, '');
      tmpIniFile.SetStrings(tmpStringList);
      tmpIniFile.UpdateFile;
   finally
      tmpIniFile.Free;
   end;
end;

oder so ähnlich (=nur kurz zusammengetippt, nicht getestet)
mir scheint es neben dem schon gesagten wichtig zu prüfen, ob '[' auch das erste Zeichen der Zeile ist, immerhin könnte ein [ auch innerhalb eines Wertes oder in einem Kommentar stehen...
Außerdem empfehle ich dir TMemIniFile, is grade bei großen Datenmengen schneller als TIniFile...


wolkenjäger - Di 23.05.06 00:13

Ein anderer Weg wäre vielleicht der:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
 ifile:=tinifile.Create('c:\test.txt');
 ifile.WriteString('Section1','Huhu11','Value');
 ifile.WriteString('Section1','Huhu12','Value'+#$0d+#$0a);
 ifile.WriteString('Section2','Huhu21','Value');
 ifile.WriteString('Section2','Huhu22','Value'+#$0d+#$0a);
 ifile.free;


Wenn man an einen der Werte ein Carriage-Return ( $0d$0a ) anhängt, wird im Texteditor automatisch ein Zeilenumbruch erzeugt. Hierbei sollte folgendes herauskommen:

[Section1]
Huhu11=Value
Huhu12=Value

[Section2]
Huhu21=Value
Huhu22=Value

... hoffe, es hilft

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt


JayEff - Di 23.05.06 14:14

Wusstest du, dass #13#10 genau das selbe ist wie #$d#$a? also hast du das selbe wie ich vorgeschlagen ^^


wolkenjäger - Mi 24.05.06 01:50

@JayEff

Du hast Recht, #13#10 und #$D#$A sind natürlich gleich - es ging mir nur darum, die Leerzeilen gleich beim Erstellen der INI-Sektionen zu erzeugen. Es genügt ein einmaliges Anhängen eines Carriage Return an z.B. den ersten zu schreibenden Wert einer Sektion.
Danach sind keine weiteren Veränderungen in der Datei mehr nötig. Die Leerzeilen sind immer an der richtigen Position, da neu eingetragene Werte in einer Sektion immer unmittelbar an die letzte dazugehörige Zeile angehängt werden. Die Leerzeilen werden also immer korrekt mitverschoben. Beim Löschen einer Sektion werden sie meines Wissens nach aber nicht gelöscht ?!?

Ciao, JD