Entwickler-Ecke

Open Source Units - FastIniFiles 3.2


Silas - Fr 31.08.07 16:21
Titel: FastIniFiles 3.2
FastIniFiles (TFIniFile)

Die Klasse TFIniFile hat im Grunde die selbe Funktion wie TIniFile, nur wird die INI-Datei komplett in einen Speicherbaum geladen und von dort aus gelesen/bearbeitet. Die Handhabung ist der von TRegistry relativ ähnlich.


Vorteile:
Beispiel:
Ein Code, der in der Datei "test.ini" aus der Sektion "testSect" die Eigenschaft "testValue" ausliest, könnte folgendermaßen aussehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
with TFIniFile.Create('test.ini'do begin
  if SectionExists('testSect'then begin 
    EnterSection; // 'testSect' wurde beim letzten Zugriff gefunden und muss nicht mehr angegeben werden
    if ValueExists('testValue'then WriteLn('testValue: ' + ReadString) // siehe oben
    else WriteLn('Konnte Eigenschaft nicht auslesen');
  end else WriteLn('Konnte Sektion nicht finden');
  Free;
end;


Speedtest: (Im Vergleich zu TMemIniFile)

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:
TMemIniFile vs. TFIniFile Speedtest
===================================

Ergebnisse:

  TMemIniFile
    Create & Free
      Große Datei: 7,328 ms
      Mittlere Datei: 2,235 ms
      Kleine Datei: 0,203 ms
    Datei auslesen (Mit Prüfung)
      Große Datei: 339,187 ms
      Mittlere Datei: 63,312 ms
      Kleine Datei: 0,797 ms
  
  TFIniFile
    Create & Free
      Große Datei: 10,766 ms
      Mittlere Datei: 3,093 ms
      Kleine Datei: 0,235 ms
    Datei auslesen (Mit Prüfung)
      Große Datei: 3,75 ms
      Mittlere Datei: 0,922 ms
      Kleine Datei: 0,16 ms

Große Datei = 100 Sektionen a 50 Eigenschaften
Mittlere Datei = 50 Sektionen a 30 Eigenschaften
Kleine Datei = 5 Sektionen a 10 Eigenschaften

Alle Tests wurden der Genauigkeit halber 1000 mal durchgeführt.


Lizenz: Die Lizenz liegt der Unit bei.


Gausi - Fr 31.08.07 16:30

Interessante Idee. Kannst du grob erläutern, wo der Vorteil deiner Klasse gegenüber TMemIniFile ist? Denn da wird das ja ähnlich gehandhabt, oder irre ich mich da?


Silas - Fr 31.08.07 17:03

:les: Oh, TMemIniFile hab ich noch gar nicht gekannt. Das macht den größten Vorteil schon einmal zunichte.
Mein zugegebenermaßen nicht so tolles Delphi-Buch sagt mir (mehr oder weniger gut), das das ganze in Stringlisten gespeichert wird (stimmt das?).

Meine Klasse speichert es als Baum, also in etwa so:
Wenn das mit den Stringlisten stimmt, wäre ein Baum schon schneller, weil kopierarbeit wegfällt.
Die "ganze Arbeit" wird bei meiner Klasse im Konstruktor ausgeführt, die Read/Write-Methoden müssen nur noch im Baum den jeweiligen Wert suchen.
Außerdem gibt es (wie bei TRegistry) eine aktuelle Sektion, sodass nicht bei jedem Vorgang die Sektion gesucht werden muss (Ich weiß nicht wie das bei TMemIniFile ist, deswegen geh ich hier von TIniFile aus).


Horst_H - Fr 31.08.07 17:42

Hallo,

eine kleine Frage:
wieso dies hier?

Delphi-Quelltext
1:
2:
Float1=123.456 #Float mit .
Float2=123,456 #Float mit ,

Wäre es nicht geschickter in der Ini Datei den Ländercode mitzuspeichern oder das Format von "Format" mit abzuspeichern??

Gruß Horst


Silas - Fr 31.08.07 18:12

Na ja, man muss immer davon ausgehen, dass in einer INI-Datei (die ja deutsch oder englisch oder was auch immer sein kann) diese Info nicht gespeichert ist. Dann kann der Parser ja nicht wissen, welches Format das verwendete ist.


BenBE - Fr 31.08.07 21:27

Ein paar Fragen:
- Ist das Kommentar-Zeichen einstellbar?
- Könnte der Parser so erweitert werden, dass man Kommentare zurückspeichern kann? (Wär doch schade, wenn meine php.ini plötzlich ohne Kommentare dastände ;-))
- Kommt deine Klasse mit doppelten Sektionen oder doppelten Einträgen klar (Sagen wir, weil ein Programm denkt, mehrzeilige Angaben durch mehrere Zeilen mit dem Gleichen Namen zu speichern?
- Kann man die Reihenfolge der Einträge beeinflussen beim Speichern?

Kennst Du TBigIniFile?
- Kann deine Klasse TColor-Werte lesen?
- Werden andere Zusatztypen unterstützt? (z.B. Sets oder Enums auslesen, wenn man die Typinfo von Delphi mitliefert)???

Ansonsten ne nette Idee; hab mir die Implementierung aber noch nicht im Detail angeschaut.


matze - Fr 31.08.07 21:57

Ja das mit dem Kommentarzeichen ist wichtig. Das muss irgendwie markiert werden.
Denn wenn ich folgenden String abspeichern möchte: Das ist das Haus #4 würde ja nur Das ist das Haus rauskommen. Du müsstest das irgendwie "escapen".

Man müsste auch direkt mal einen Speedtest durchführen: FastIniFiles vs MemIniFile


Silas - So 02.09.07 12:28

user profile iconBenBE hat folgendes geschrieben:
Ist das Kommentar-Zeichen einstellbar?
Ab jetzt schon. :) (Der Konstruktor hat einen zweiten Parameter bekommen)
user profile iconBenBE hat folgendes geschrieben:
Könnte der Parser so erweitert werden, dass man Kommentare zurückspeichern kann?
Schwierig. Das ist ein Nachteil der Baumstruktur. Wenn du die Datei nicht bearbeitest, bleibt sie ja unverändert. Es gäbe die Möglichkeit, für jede Eigenschaft die Kommentare davor bzw. danach abzuspeichern, aber ob dass so effizient ist... Ich werd's mal versuchen, aber wenn jemand eine bessere Idee hat, freu' ich mich natürlich.

user profile iconBenBE hat folgendes geschrieben:
Kommt deine Klasse mit doppelten Sektionen oder doppelten Einträgen klar (Sagen wir, weil ein Programm denkt, mehrzeilige Angaben durch mehrere Zeilen mit dem Gleichen Namen zu speichern?
Auch noch nicht. Aber ich könnte es so ändern, dass er in diesem Fall eine Stringliste verwendet, oder dass es ein Zeilen-Fortsetzungs-Zeichen (wie in manchen Sprachen der Backslash) gibt (Das zweite wäre natürlich einfacher).

user profile iconBenBE hat folgendes geschrieben:
Kann man die Reihenfolge der Einträge beeinflussen beim Speichern?
Nein, das ist wieder ein Problem mit der Baumstruktur. Die neuesten Einträge landen immer unten in der Sektion bzw. in der Datei.

user profile iconBenBE hat folgendes geschrieben:
Kennst Du TBigIniFile?
Nein :wink: (Hab auf die Schnelle jetzt auch nichts gefunden)

user profile iconBenBE hat folgendes geschrieben:
Kann deine Klasse TColor-Werte lesen?
Ist das nicht ein Integer?

user profile iconBenBE hat folgendes geschrieben:
Werden andere Zusatztypen unterstützt?
Bis jetzt nur String, Integer, Boolean und Extended. Werd' aber noch eine ReadBinary und WriteBinary-Methode einbauen.


user profile iconmatze hat folgendes geschrieben:
Man müsste auch direkt mal einen Speedtest durchführen: FastIniFiles vs MemIniFile

Voilà: Siehe erster Post
Schaut euch das Ergebnis an. :beer:


Silas - Sa 05.01.08 15:16

So, nach einem knappen halben Jahr: Ein neues Release! (Version 2.0)
[+] Read/WriteBinary - Funktionen: Schreiben/Lesen beliebige Werte (z.B. Records, GUIDs) als hexadezimalen string in die/aus der Datei.
[+] Escapede Strings: Schreiben/Lesen nach C-Art escapede Strings ((un)escaped werden die Whitespaces, sodass beispielsweise mehrzeilige und/oder mit Tabs/Leerzeichen formatierte Werte gespeichert werden können
[+] Eine Clear-Prozedur: Löscht den Inhalt der gesamten Datei
[+] Dazu gehörend eine ClearSection-Prozedur: löscht den Inhalt einer Sektion
[+] Zugriffsbeschleunigung: Wenn z.B. die existenz einer Sektion mit SectionExists abgefragt wurde, muss bei EnterSection der Name nicht erneut angegeben werden, da die Klasse nun die Daten (also den Index im Array) des letzten Zugriffs speichert.
[+] Int64: Read/WriteInteger speichert/liest nun Int64-Werte
[*] Die ReadInteger/Bool/Float-Funktionen lösen bei einem Konvertierungsfehler nun keine Exception mehr aus, sondern geben einen Standardwert zurück (0, false, 0.0)
[*] Ein paar unwichtige Optimierungen
[*] Die Exception-Typen EIniSectionNotFound und EIniValueNotFound wurden zu EIniEntryNotFound zusammengefasst.

Ich werde, sobald wie möglich, eine Funktion zum speichern der Kommentare schreiben. Die Formatierungen wie führende Leerzeichen und Leerzeilen (ohne Kommentarzeichen) würde ich dann aber außer Acht lassen.


Silas - Mo 04.02.08 12:22

Nochmal ein Neues Release (Version 2.1):
[+] RenameSection/RenameValue-Funktionen: Benennen Eigenschaften und Funktionen um
[+] WriteString/ReadString escaped wenn auch Kommentarzeichen (zu \c)
[*] Bugfix: Ein Bug, der das Einlesen von gleichnamigen Eigenschaften in verschiedenen Sektionen verhindert hat, wurde behoben
[*] Ein paar unwichtige (Architektur-)Veränderungen

Download im ersten Posting.

Ich schreib gerade an der Kommentar-Funktion, erweist sich allerdings als schwierig.


Gahero - Di 05.02.08 15:35

Geile Sache.
Bin gerade am überlegen, ob ich mein Projekt, was demnächst mal wieder eine Frischzellenkur braucht auf Fastinifiles umzustellen. Gibts noch andere Vorteile außer bessere Geschwindigkeiten bei größeren Datenmengen und speichern von anderen Datentypen?


Silas - Di 05.02.08 16:22

user profile iconGahero hat folgendes geschrieben:
Geile Sache.
Bin gerade am überlegen, ob ich mein Projekt, was demnächst mal wieder eine Frischzellenkur braucht auf Fastinifiles umzustellen.

Danke. Freut mich sehr.

user profile iconGahero hat folgendes geschrieben:
Gibts noch andere Vorteile außer bessere Geschwindigkeiten bei größeren Datenmengen und speichern von anderen Datentypen?



Heiko - Di 05.02.08 18:14

Hallo Silas,

es gibt eine Stelle, dir mir bei OpenSource-Units immer gleich einfällt, wo eine Fehlerstelle ist ;).

Versuch mal eine ini zu öffnen, wo der Pfad folgendermaßen ist ;):


Quelltext
1:
C:\Нас Не Дагонят\test.ini                    


Wie du dort sehen wirst, scheitert deine Unit daran. UniCode-Support wäre also nicht schlecht (ich hab hier in der Sparte ne Unit dafür liegen, falls du die verwenden möchtest. Alternativ kannste ja auch einen constructor für TFile anbieten, so dass er die Daten auch von MemoryStreams annehmen kann).


Silas - Di 12.02.08 20:05

Danke für die Antwort! Die Idee mit den Streams ist interessant, aber der Destruktor muss das Ganze ja wieder speichern können... Soll ich dann einfach dem Destruktor einen Parameter geben, oder wie hast du das gemeint?


Heiko - Di 12.02.08 20:22

Wenn man im constructor einen Stream übergibt, erhält man ja eigentlich nur eine Referenz, mit der du arbeitren kannst. Diese behällst du dir als private-Var in der Klasse. Sobald der destructor aufgerufen wird, verwendest du die einfach weiter. Das birgt zwar ein paar mögliche Fehlerstellen (ein anderer gibt hat die Klasse bereits freigegeben), aber es gibt eben immer Schwachpunkte ;). Du kannst natürlich dem destructor auch eine Variable geben. Nimm einfach das, was dir am besten gefällt.


Silas - Di 12.02.08 20:45

Das war das Problem, das ich gemeint habe. Ich denke, ich werde jetzt erst einmal den Unicode-Support aus deiner Unit (mit internem Stream natürlich) und dann vielleicht einen Read-Only-Modus für Streams schreiben. Lassen sich z.B. Resource-Streams überhaupt schreiben?


Heiko - Di 12.02.08 21:16

user profile iconSilas hat folgendes geschrieben:
Ich denke, ich werde jetzt erst einmal den Unicode-Support aus deiner Unit (mit internem Stream natürlich)

Ich werde die Woche dafür sicherlich ein Update rausbringen, womit das umstellen auf TStream nur noch ein minimaler Compilierschalter ist (habs gerade auf die schnelle probiert, aber Borland nutzt an der einen Stelle Int64, wo ich nur Cardinal nutze, wes wegen ich an ein paar Stellen mehr den Compilierweichen einbauen muss).

user profile iconSilas hat folgendes geschrieben:
und dann vielleicht einen Read-Only-Modus für Streams schreiben.

Wäre eine Möglichkeit. An der Stelle vlt. einen alterativen Destruktor anbeiten, der das auch dann schreiben kann.

user profile iconSilas hat folgendes geschrieben:
Lassen sich z.B. Resource-Streams überhaupt schreiben?

Du meinst bezüglich meiner Unit? Wenn du die auf TStreams basieren lässt wahrscheinlich. Ich habs bisher nicht gebraucht, von daher auch nicht getestet ;).


Silas - Di 12.02.08 22:56

user profile iconHeiko hat folgendes geschrieben:
Ich werde die Woche dafür sicherlich ein Update rausbringen, womit das umstellen auf TStream nur noch ein minimaler Compilierschalter ist.

Ich hätte gedacht das wär schon so? Oder war es gar nicht die [http://www.delphi-forum.de/viewtopic.php?t=62275&start=0&postdays=0&postorder=asc], die du gemeint hast?

user profile iconHeiko hat folgendes geschrieben:
user profile iconSilas hat folgendes geschrieben:
Lassen sich z.B. Resource-Streams überhaupt schreiben?

Du meinst bezüglich meiner Unit? Wenn du die auf TStreams basieren lässt wahrscheinlich. Ich habs bisher nicht gebraucht, von daher auch nicht getestet ;).

Nein, ich meine TResourceStream, mit dem man auf Ressourcen zugreifen kann. Ich denke nicht, dass man auf so einen Stream (wirklich) schreiben kann, oder? Schließlich ist die Resource ja in der EXE verankert...

Das mit dem alternativen Destruktor werd ich wahrscheinlich so machen :) .


Heiko - Mi 13.02.08 08:12

user profile iconSilas hat folgendes geschrieben:
Oder war es gar nicht die [http://www.delphi-forum.de/viewtopic.php?t=62275&start=0&postdays=0&postorder=asc], die du gemeint hast?

Doch die meine ich ;). Wenn ich dich richtig verstanden habe, willst du ja als Grundobjekt nicht TObject haben, sondern TStream. Um beide Variante zu erlauben, kommt demnächst ein Compilierschalter rein, da ich TStrea,m bisher außebn vorgelassen habe.

user profile iconSilas hat folgendes geschrieben:
Nein, ich meine TResourceStream, mit dem man auf Ressourcen zugreifen kann.

Achso, den muss ich mir mal angucken. Ich hab schon eigentlich geguckt, ob in Classes ein weiterer Stream ist, aber den habe ich wohl übersehen ;).


Silas - Mi 13.02.08 17:23

user profile iconHeiko hat folgendes geschrieben:
user profile iconSilas hat folgendes geschrieben:
Oder war es gar nicht die [http://www.delphi-forum.de/viewtopic.php?t=62275&start=0&postdays=0&postorder=asc], die du gemeint hast?

Doch die meine ich ;). Wenn ich dich richtig verstanden habe, willst du ja als Grundobjekt nicht TObject haben, sondern TStream. Um beide Variante zu erlauben, kommt demnächst ein Compilierschalter rein, da ich TStrea,m bisher außebn vorgelassen habe.

Nein, nein, ich will schon TObject als Elternklasse lassen, nur den Konstruktor umschreiben, dass er mit Streams arbeitet, und anschließend diesen wieder für Dateien überladen, dass der Parser selbst also nur noch mit Streams arbeitet. Denk ich, wäre sinnvoller, weil ja ein Parser (als Klasse) nicht viel mit Streams am Hut hat und ich sonst die ganzen Read / Write Methoden überladen muss, bloß mit was? :wink:


Heiko - Mi 13.02.08 17:39

Die Streams brucht du doch nur zum Laden bzw. Speichern. Das zeug dazwischen würde ich nicht per Streams machen, da dass eine aufwändige umkopiererrei ist.

PS: Kannst du mal von deinem letzten Post kurz Pseudocode oder ähnliches geben, damit ich weiß, was du meinst? Denn ich sehe da gerade nicht ganz durch, was du genau meinst (oder ich muss ihn mir später nochmal angucken, wenn meine Gedanken von der Schule endgültig erlöst sind :mrgreen:)


Silas - Mi 13.02.08 18:02

user profile iconHeiko hat folgendes geschrieben:
Die Streams brucht du doch nur zum Laden bzw. Speichern. Das zeug dazwischen würde ich nicht per Streams machen, da dass eine aufwändige umkopiererrei ist.

So mein ich des ja :)

user profile iconHeiko hat folgendes geschrieben:
PS: Kannst du mal von deinem letzten Post kurz Pseudocode oder ähnliches geben, damit ich weiß, was du meinst? Denn ich sehe da gerade nicht ganz durch, was du genau meinst (oder ich muss ihn mir später nochmal angucken, wenn meine Gedanken von der Schule endgültig erlöst sind :mrgreen:)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
type
  TFIniFile = class 
    private
      //...
    public
      constructor Create(const Stream: TStream); overload//Der Parser selbst, neue Version
      constructor Create(const FileName: String); overload//Die überladene Version, die einen Dateinamen übernimmt und ihn als FileStream an den ersten Konstruktor weitergibt
      //...
  end;

Ich mein, einen Parser von TStream abzuleiten macht wenig Sinn, weil ein Parser ja kein Stream ist :wink:


Heiko - Mi 13.02.08 21:08

user profile iconSilas hat folgendes geschrieben:
Ich mein, einen Parser von TStream abzuleiten macht wenig Sinn, weil ein Parser ja kein Stream ist :wink:

Ah k, dass meinst du. Mich hatte letztens dieser Satz gestört ;):

user profile iconSilas hat folgendes geschrieben:
dass der Parser selbst also nur noch mit Streams arbeitet

Du meinst also, dass der Dateiconstruktor den Streamconstructor aufruft, nur mit nem selbst erzeugtem Stream. Sag das doch gleich :twisted: .


Silas - Mi 13.02.08 21:54

user profile iconHeiko hat folgendes geschrieben:
user profile iconSilas hat folgendes geschrieben:
dass der Parser selbst also nur noch mit Streams arbeitet

Du meinst also, dass der Dateiconstruktor den Streamconstructor aufruft, nur mit nem selbst erzeugtem Stream. Sag das doch gleich :twisted: .

Der Parser selbst ist ja der Konstruktor... :D
OK ich hab mich vielleicht ein bisschen komisch ausgedrückt :wink:


Silas - So 17.02.08 17:09

So, die neue Version 2.2 ist fertig!
[*] Die Lese- und Schreibmethoden für die Datei arbeiten nun intern mit Streams
[- ] Die SaveAs-Methode fällt weg, dafür akzeptiert Save nun einen Dateinamen-Parameter
[+] Create kann nun auch mit Streams aufgerufen werden
[+] Save kann nun in Streams speichern
[+] Bei ReadBinary kann nun auch der erste Parameter weggelassen werden, das hatte ich vergessen.
[*] Die Unit ist noch ein bisschen schneller geworden :), weil ich für das Einlesen eine Stringliste verwendet hab, die den Vorteil bietet, dass die ganze Datei auf einmal gelesen wird.

(Download im ersten Posting.)


Und es gibt einen neuen Speedtest. Beim Auslese-Test wird nun vorher überprüft, ob der Wert auch existiert. Hier macht sich die Funktion des leztzen Zugriffs deutlich bemerkbar: FastIniFiles ist hier nun bei allen Dateien (klein, mittel, groß) ca. 100 mal schneller als TMemIniFile :!: Außerdem ist in den verschiedenen Dateien auch die Anzahl der Einträge pro Sektion anders. Beim Einlesen liegt TMemIniFile logischerweise weiterhin vorne und ist dort ca. doppelt so schnell.
Das Ergebnis steht nun im ersten Posting, wo ihr den Speedtest auch runterladen könnt. Vorsicht, die neue Version braucht ziemlich viel Zeit, auf meinem (1 x 1.4GHz-) Rechner hat er eine Viertelstunde gedauert.


alzaimar - Di 19.02.08 22:35

user profile iconSilas hat folgendes geschrieben:
Und es gibt einen neuen Speedtest. Beim Auslese-Test wird nun vorher überprüft, ob der Wert auch existiert. Hier macht sich die Funktion des leztzen Zugriffs deutlich bemerkbar: FastIniFiles ist hier nun bei allen Dateien (klein, mittel, groß) ca. 100 mal schneller als TMemIniFile :!:

Also das ist Selbstbetrug. Du testest doch so, das Du einen Wert 1000x liest. Und wenn du das dann optimierst, ist es ja wohl logisch, das dein 'SpeedTest' so ein Ergebnis bringt. Überlege Dir lieber, wie eine Ini-Datei im allgemeinen benutzt wird. Imho werden Werte zufällig gelesen und geschrieben, und nicht 10000x der gleiche Wert.

Bei der Gelegenheit wäre es interessant, den Quelltext von deinem Speedtest zu veröffentlichen. Mal sehen, wie TBigIni da abschneidet.


Silas - Mi 20.02.08 14:47

Das habe ich ja nicht optimiert. Der Geschwindigkeitsvorteil von FastIniFiles liegt zwischen ValueExists und ReadValue, und nicht zwischen zwei Lesevorgägen. ValueExists sucht den Wert immer neu, egal auf welchen vorher zugegriffen wurde. Das ist von praktischem Nutzen, weil man zumindest wenn man sauber programmiert, überprüfen sollte, ob ein Wert vorhanden ist, bevor man ihn benutzt. Die Unit ist hier bei 1000 verschiedenen Werten genauso schnell wie bei 1000 gleichen (zumindest relativ zu TMemIniFile, weil die Dateigröße ja steigen würde).
Der Quelltext liegt dem Speedtest, den du im ersten Posting runterladen kannst, schon bei.


alzaimar - Mi 20.02.08 17:26

silas: Ash on my Haupt.


Silas - Sa 29.03.08 15:45

Moin zusammen! :wave:

Es gibt (mal wieder) ein "Zwischenrelease" zum "großen" FastIniFiles 3.0, bei dem Unicode und Kommentare implementiert sein werden. 3.0 ist schon recht weit, aber noch lange nicht fertig. Diese Version ist daher haupsächlich ein Bugfixrelease.
Zusammen mit diesem Release habe ich auch Versionsnummern für die Unit eingeführt.

Neue Version 2.3
[+] Es gibt nun ReadValueDef-Methoden für alle Lesevorgänge , die bei einem nichtexistierenden Wert oder einem Konvertierungsfehler einen Defaultwert zurückgeben
[*] Ein Bug, der u.U. das schreiben einer nichtexistierenden Datei verhinderte, wurde behoben
[*] Ein weiterer Bug, der u.U. das korrekte Lesen eines Strings verhinderte, wurde ebenfalls behoben

Ich freu' mich natürlich weiterhin über Feedback :)


Silas - Sa 05.04.08 19:57

So, da ist sie: Version 3.0
[+] Der Parser speichert nun Kommentare sowie Leerzeilen zurück
[*] Der Code wurde ein wenig überarbeitet
[+] Der Quelltext hat die 1000-Zeilen-Marke überschritten ;)

Die Unicode-Unterstützung konnte ich leider noch nicht fertigstellen, da es noch ein Problem mit user profile iconHeikos Unicode-Unit gibt. Die wichtigste Änderung ist aber geschehen, deswegen denke ich, 3.0 ist gerechtfertigt.
Dafür habe ich mir aber "Typsicherheit" (a la name:type=value) in mein TODO geschrieben. Das wäre die erste Veränderung, die den INI-Standard "sprengen" würde, mal sehen, wie ich das implementiere :)


Gahero - So 06.04.08 21:44

Ich bin leider noch nicht dazu gekommen, sie in mein Projekt einzubauen, hab ne ganze Menge anderes Zeug um die Ohren im Moment, aber demnächst werde ich das wohl angehen.
Meinen Respekt haste, weiter so... Wenn das Teil demnächst mehr sinnvolle und vorallem neue Features hat, die man nicht standardmäßig hat, wirds vllt auch mehr Leute interessieren die hier posten...


Silas - Mo 07.04.08 14:39

user profile iconGahero hat folgendes geschrieben:
Meinen Respekt haste, weiter so...
Vielen Dank!

user profile iconGahero hat folgendes geschrieben:
Wenn das Teil demnächst mehr sinnvolle und vorallem neue Features hat, die man nicht standardmäßig hat, wirds vllt auch mehr Leute interessieren die hier posten...
Freilich bemühe ich mich immer, neue Features einzubauen (wenn mir welche einfallen). Das Problem ist nur: Wenn mir niemand Vorschläge macht, was ich denn verbessern könnte, dauert es natürlich wesentlich länger, bis es etwas neues gibt.


Gahero - So 27.04.08 10:57

Habe jetzt endlich mal angefangen die Unit in mein Proj einzubauen.

Ich benutzte folgenden Code für meine Sprachdateien: (nur ein Auszug, der Rest ist ähnlich aufgebaut)

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:
with TFIniFile.Create(ExtractFilePath(ParamStr(0)) + 'data/lang/lang_new.ini'do
  begin


    for i := 1 to Frm.ComponentCount - 1 do
    begin

      compo := Frm.Components[i];

      {entersection('Test');
      writestring('test', 'test');}


      if (compo is TLabel) then
      begin
        Entersection('TLabel');
        WriteString((compo as TLabel).Name, (compo as TLabel).Caption);
      end;

    if (compo is TBitBtn) then
    begin
      Entersection('TBitBtn');
      WriteString((compo as TBitBtn).Name, (compo as TBitBtn).caption);
    end;

    end;

    Free;

  end;


Nachdem ich den Code für FastIniFile umgebaut habe, bringt er mir allerdings jedes Mal, wenn ich den Code oben aufrufe folgenden Fehler:
Zugriffsverletzung. (in der Zeile 621 " if Length(Value) > 0 then begin" Prozedure Save) Vorher mit TIniFile hat noch alles geklappt. Ist mein Code falsch oder hab ich nen Bug gefunden?


Silas - So 27.04.08 19:41

Moin Gahero,

werde mir das Problem morgen mal ansehen...
Bist du sicher, dass du die letzte Version (3.0, vom 5. April) verwendest? Ich kann mich dunkel daran erinnern, so etwas gefixt zu haben. Dein Quelltext an sich ist soweit fehlerfrei (und der Fehler tritt ja in meiner Unit auf).


Gahero - So 27.04.08 19:54

Hi,

habe die neuste Version 3.0. Ich habe oben auch noch den ersten kommentierten Code ausprobiert, der klappt ohne Probleme...


Silas - Mo 28.04.08 21:12

Ich habe den Bug gefunden und soweit behoben, allerdings ist er bei mir an einer anderen Stelle aufgetreten (was u.U. mit der Bereichsprüfung zusammenhängt).
Für diesen minimalen Fix spare ich mir eine Versionsnummer, sie ist weiterhin 3.0. :wink:
Die Projekt-Zip ist aktualisiert, du kannst sie im ersten Posting runterladen.


Gahero - Di 29.04.08 12:19

Ok, also mit der gefixten Version geht es ohne Probleme. Vielen Dank für das schnelle Update!


Regan - Do 08.05.08 19:59

user profile iconSilas hat folgendes geschrieben:
Freilich bemühe ich mich immer, neue Features einzubauen (wenn mir welche einfallen). Das Problem ist nur: Wenn mir niemand Vorschläge macht, was ich denn verbessern könnte, dauert es natürlich wesentlich länger, bis es etwas neues gibt.

Dann versuch ich hier mal meine Vorschläge mit einzubeziehen: Wie wäre die Funktion, dass, wenn man eine Sektion geöffnet hat, man alle Werte auslesen kann.
Ansonsten funktioniert deine Unit sehr gut. Ich bin voll und ganz zufrieden :zustimm: .


Silas - Do 08.05.08 22:36

user profile iconRegan hat folgendes geschrieben:
Wie wäre die Funktion, dass, wenn man eine Sektion geöffnet hat, man alle Werte auslesen kann.
Gute Idee. Was hast du dir denn so als Ziel fürs Auslesen vorgestellt? Eine Stringlist (bzw. ein TStrings) oder eher ein String- oder gar ein Variant-Array?
Vielleicht könnte man in dieser Methode auch noch eine Filterfunktion einbauen.

user profile iconRegan hat folgendes geschrieben:
Ansonsten funktioniert deine Unit sehr gut. Ich bin voll und ganz zufrieden :zustimm: .
Vielen Dank, freut mich.


Regan - Fr 09.05.08 10:58

user profile iconSilas hat folgendes geschrieben:
user profile iconRegan hat folgendes geschrieben:
Wie wäre die Funktion, dass, wenn man eine Sektion geöffnet hat, man alle Werte auslesen kann.
Gute Idee. Was hast du dir denn so als Ziel fürs Auslesen vorgestellt? Eine Stringlist (bzw. ein TStrings) oder eher ein String- oder gar ein Variant-Array?
Vielleicht könnte man in dieser Methode auch noch eine Filterfunktion einbauen.

Das würde ich eigentlich dir überlassen. Aber eine StringList mit den Namen würde mir eigentlich schon zureichen.


Silas - Fr 09.05.08 12:54

user profile iconRegan hat folgendes geschrieben:
Aber eine StringList mit den Namen würde mir eigentlich schon zureichen.

Ach so, ich hätte gedacht du meinst nicht die Namen, sondern die Werte. Das kommt auf jeden Fall mal so rein, vielleicht auch noch Methoden fürs Auslesen der Werte, mal sehen, ob mir was ordentliches einfällt. :)


Regan - Fr 09.05.08 16:08

user profile iconSilas hat folgendes geschrieben:
user profile iconRegan hat folgendes geschrieben:
Aber eine StringList mit den Namen würde mir eigentlich schon zureichen.

Ach so, ich hätte gedacht du meinst nicht die Namen, sondern die Werte. Das kommt auf jeden Fall mal so rein, vielleicht auch noch Methoden fürs Auslesen der Werte, mal sehen, ob mir was ordentliches einfällt. :)

Nur nochmal zur Absicherung:
Ini hat folgendes geschrieben:
[testSection]
testName=testWert

Die meine ich :wink: .


Heiko - Fr 09.05.08 19:29

Hallo Silas,

kannst bitte in dem Threadtitel die aktuelle Versionsnummer mit einbauen? Denn bei Thunderbird denke ich immer: "nicht schon wieder nen Post dort", wenn dagegen auf einmal ne neue Versionsummer auftaucht, denke ich immer: "Ah mal schaun, was es neues gibt" :mrgreen: .


Silas - Fr 09.05.08 22:36

user profile iconRegan hat folgendes geschrieben:
Nur nochmal zur Absicherung:
Ini hat folgendes geschrieben:
[testSection]
testName=testWert

Die meine ich :wink: .
Gut. Ich auch ;) .


user profile iconHeiko hat folgendes geschrieben:
kannst bitte in dem Threadtitel die aktuelle Versionsnummer mit einbauen?
Bitteschön! ;)


Silas - Di 13.05.08 17:08

Dieses Release ist doch deutlich dicker geworden, als ich es ursprünglich geplant hatte. Das Feature mit der Werteliste habe ich auch auf Sektionen ausgedehnt, und in Verbindung damit könnt ihr auf die Einträge auch über Indizes zugreifen (Das gilt sowohl für EnterSection als auch für ReadValue und DeleteEntry). Die Funktion zum Wiederherstellen einzelner Einträge könnte für den einen oder anderen ganz interessant sein, der alle Werte bis auf einige wenige löschen will.

Neue Version 3.1
[+] Es gibt nun die Möglichkeit, die Sektions- und Wertenamen in eine Stringliste zu exportieren
[+] Im Zusammenhang ist es nun möglich, sowohl die Sektionen als auch die Werte mit Indizes anzusprechen
[*] Ein Bug in den Binary-En/Decode-Methoden wurde beseitigt (Danke @ user profile iconBenBE)
[+] Im Destruktor kann jetzt angegeben werden kann, ob Änderungen gespeichert werden sollen
[+] Gelöschte Sektionen und Werte können wiederhergestellt werden.
[*] Ein Bug, der Empty falsch zurückgegeben hat, wurde gefixt
[+] Die betretene Sektion kann jetzt verlassen werden (hat im Moment noch nicht viel Sinn)
[*] Und noch ein paar unwichtige Änderungen


Regan - Di 13.05.08 20:43

user profile iconSilas hat folgendes geschrieben:
Dieses Release ist doch deutlich dicker geworden, als ich es ursprünglich geplant hatte. Das Feature mit der Werteliste habe ich auch auf Sektionen ausgedehnt, und in Verbindung damit könnt ihr auf die Einträge auch über Indizes zugreifen (Das gilt sowohl für EnterSection als auch für ReadValue und DeleteEntry). Die Funktion zum Wiederherstellen einzelner Einträge könnte für den einen oder anderen ganz interessant sein, der alle Werte bis auf einige wenige löschen will.

Da bringt mir die neue Version ja gleich doppelt etwas. Sehr gut :zustimm: .


Silas - So 18.05.08 14:31

user profile iconRegan hat folgendes geschrieben:
Sehr gut :zustimm: .

Vielen Dank! Da schieb ich doch gleich noch ein Release nach: :)

Version 3.2
[+] Die Unit arbeitet jetzt mit einer eigenen, schnelleren Char-Pos-Funktion
[+] Die Read-/WriteBinary-Methoden arbeiten jetzt auch mit Streams
[*] Alle Assembler-Methoden wurden überarbeitet
[*] Ein Fehler, der bei Read-/WriteBinary Probleme mit einigen Bytecodes verursacht hat, wurde behoben
[+] Der Parser/Writer arbeitet jetzt mit einem MemoryStream als Zwischenspeicher
[+] Stringlisten (TStrings) lassen sich nun über ReadStringList/WriteStrinList lesen/schreiben
[+] WriteValue-Methoden akzeptieren jetzt ebenfalls Indizes
[*] Die Read-/WriteBool-Methoden verwenden nun Standardmäßig Boolean-Strings ('true', 'false') anstatt von 0 und 1
[*] WriteFloat schreibt Floats jetzt standardmäßig mit '.' als DecimalSeparator


Mit dem Stream-Handling haben jetzt alle Geeks unter euch, die schon immer mal Screenshots und DVD-Rips in INIs speichern wollten, endlich die Möglichkeit dazu ;).

Die Boolean-Methoden sind trotz dem, dass sie ab jetzt Strings schreiben, zu 0 und 1 abwärtskompatibel. Bei der Erkennung true/false wird, wie unter C üblich, alles, was nicht false ist, als true angenommen.

Natürlich freu' ich mich weiterhin über Feedback :)


Regan - So 18.05.08 14:37

Mir ist noch was aufgefallen: Bei der procedure ListValues, könntest du da bitte als ersten Parameter auch eine Sektion angeben, sonst muss ich die immer vorher aufrufen?


Silas - So 18.05.08 19:48

user profile iconRegan hat folgendes geschrieben:
Bei der procedure ListValues, könntest du da bitte als ersten Parameter auch eine Sektion angeben, sonst muss ich die immer vorher aufrufen?

Hm, ich glaube, das würde mir mein Konzept ein wenig durcheinanderwerfen :? . Das ist doch auch nur eine Zeile mehr.

Für welchen Zweck brauchst du's denn? Wenn man eine Werteliste abruft, dann doch meistens, um nachher darauf zuzugreifen.


Gahero - So 18.05.08 20:24

Ich würde das so lassen, da grenzt du dich mehr von der normalen TInifile noch mehr ab und der Code wird (finde ich) übersichtlicher. Die neuen Features sind echt gelungen, das kann ich gut gebrauchen... Weiter so.


BenBE - So 18.05.08 20:57

Könnte man doch mit drei Befehlen machen:

1. einer ohne Parameter (aktuelle Sektion)
2. per Index (öffnet die Sektion intern, ruft die parameterlose Version auf und schließt die Sektion nachher wieder)
3. per Name (halt wie 2., nur mit Name statt Index zur Identifikation der Sektion)

Damit sollte jeder seinen Lieblingsweg haben.


Silas - So 18.05.08 21:41

user profile iconGahero hat folgendes geschrieben:
Ich würde das so lassen, da grenzt du dich mehr von der normalen TInifile noch mehr ab und der Code wird (finde ich) übersichtlicher.
Ich finde auch, dass die Änderung hier nicht wirklich sinnvoll ist, weil sie keine neue Funktionalität enthält und damit IMHO zu einem schlechten Design führt.

user profile iconGahero hat folgendes geschrieben:
Die neuen Features sind echt gelungen, das kann ich gut gebrauchen... Weiter so.
Vielen Dank! Werd mich bemühen. :)

user profile iconBenBE hat folgendes geschrieben:
Könnte man doch mit drei Befehlen machen:

1. einer ohne Parameter (aktuelle Sektion)
2. per Index (öffnet die Sektion intern, ruft die parameterlose Version auf und schließt die Sektion nachher wieder)
3. per Name (halt wie 2., nur mit Name statt Index zur Identifikation der Sektion)
So hätte ich das denke ich auch gelöst.


@user profile iconRegan: In welchem Zusammenhang bzw. warum lässt du eine Werteliste erstellen ohne nachher auf die Werte zuzugreifen? Wie sieht in dem Fall das Design-Konzept von deiner INI aus?


Regan - Di 20.05.08 17:22

user profile iconSilas hat folgendes geschrieben:
@user profile iconRegan: In welchem Zusammenhang bzw. warum lässt du eine Werteliste erstellen ohne nachher auf die Werte zuzugreifen? Wie sieht in dem Fall das Design-Konzept von deiner INI aus?

Ic glaube ich habe mich da etwas falsch ausgedrückt. Ich wollte noch zusätzlich den Parameter Sectionname.
Also dann so: procedure ListValues(const nName: String; Dest: TStrings);.
Sonst muss ich vorher immer die Section betreten. Das ist aber manchmal echt bescheuert sehr ungünstig, da ich manchmal nur einen Wert abfragen will, oder, wie bei ListValues, nur die Werte auslesen will und im Endeffekt in dem weiteren Codeabschnitt nichts mehr damit anfange.

Ich hoffe das war verständlicher ausgedrückt.


Silas - Di 20.05.08 18:28

Hm...


Ohne Änderung
1:
2:
3:
4:
5:
for i := 0 to 255 do 
  if SectionExists('MySection' + IntToStr(i)) then begin
    EnterSection;
    ListValues(MySectionValues[i]);
  end;


Mit Änderung
1:
2:
3:
for i := 0 to 255 do
  if SectionExists('MySection' + IntToStr(i)) then
    ListValues('MySection' + IntToStr(i), MySectionValues[i]);

Wo ist beim ersten Code der Mehraufwand? :gruebel:   Es fällt gerade mal ein begin-end-Block raus.

Code- oder Geschwindigkeitstechnisch würde sich auch nichts ändern, weil diese Version einfach nur die Aufrufe nacheinenader ausfürhen würde... Bin mir jetzt aber nicht sicher, ob ich dein Problem richtig verstanden hab. :nixweiss:


Vielleicht noch ein Tipp zur Strukturierung einer INI:
Ich hab mir da eine Methode angewöhnt, mit der ich eigentlich immer recht zufrieden bin. Die Sektionen sind immer eindeutig einer Funktion zugeordnet, eine z.B. für die Einstellungen, eine als "Datenbank", usw. Die meinsten meiner INIs haben deswegen auch nur eine einzige Sektion.
Die Werte leg ich immer im "OOP-Style" an, d.h. bei mehreren, durchnummerierten a la <Nummer>.[<Kategorie>.]<Wertname> .


Ein Beispiel
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
[items]
count=3
0.id=57a3e1425
0.name=myitem1
0.pos.left=20
0.pos.top=15
1.id=f9f2315ab
1.name=myitem2
1.pos.left=35
1.pos.top=10
2.id=a163c057d
2.name=myitem3
2.pos.left=85
2.pos.top=110

So lässt sich der Inhalt auch recht schnell und sauber in schleifen auslesen.


Hendi48 - Mi 10.09.08 19:16

Ich kann die Unit in Delphi 2009 nicht compilen :(
Es scheitert an der Funktion CharPos, Zeile 1470:

Delphi-Quelltext
1:
mov al, Chr             // Chr suchen                    

[DCC Fehler] FastIniFiles.pas(1470): E2107 Operandengröße stimmt nicht überein
Ich glaube da wurde was für Unicode Support geändert..


BenBE - Mi 10.09.08 19:19

Versuch mal

Quelltext
1:
MOV AL, BYTE PTR [Chr]                    


Hendi48 - Mi 10.09.08 19:55

Danke, so geht es!


dummzeuch - Mi 10.09.08 20:38

Eine Funktion, die ich fuer .ini Files haeufiger brauche, ist der Vergleich von zwei Dateien. Prinzipiell ginge das auch mit einem File-Differ, aber leider funktioniert das nur, wenn sich die Reihenfolge der Eintraege nicht geaendert hat.

Kann man vielleicht mit Deiner Klasse die Eintraege in einer bestimmten Reihenfolge abspeichern, so dass man zwei .ini Files damit in eine vorgegebene Reihenfolge bringen kann, um sie anschliessend zu vergleichen?

(Oder kennt vielleicht jemand ein Tool, was zwei .ini Files vergleicht?)


Heiko - Mi 10.09.08 20:45

ToroiseSVN kann Textdateien vergleichen. Und nix weiter ist ja eine INI. Probier es mal damit. Vlt reicht es dir (sortieren tut der natürlich nicht).


BenBE - Mi 10.09.08 21:15

Dann sollte er aber nicht TortoiseMerge nehmen, sondern WinMerge; der erkennt auch verschobene Blöcke korrekt.


Heiko - Mi 10.09.08 21:25

Möglich. Ich habe TortioseSVN oben aber WinMerge nicht (zu mindestens nicht bewusst). Von daher habe ich mit letzterem keine Erfahrung. Auf jeden Fall wäre die Erkennung von verschobene Blocks brauchbar.

Ansonsten: Ich würde ein INI-Vergleich nicht in die Unit einbauen. Das ist zu spezifisch und könnte eigentlich auch mit einem beliebigen Textmerger erreicht werden.


Boldar - Mi 10.09.08 21:26

user profile iconHeiko hat folgendes geschrieben:

Ansonsten: Ich würde ein INI-Vergleich nicht in die Unit einbauen. Das ist zu spezifisch und könnte eigentlich auch mit einem beliebigen Textmerger erreicht werden.


Naja, wenn aber die Reihenfolge anders ist??


Heiko - Mi 10.09.08 21:30

Wie BenBE es sagte: probier WinMerge. Gute Merger erkennen umsortierung ;).


dummzeuch - Do 11.09.08 15:01

user profile iconHeiko hat folgendes geschrieben:
ToroiseSVN kann Textdateien vergleichen. Und nix weiter ist ja eine INI. Probier es mal damit. Vlt reicht es dir (sortieren tut der natürlich nicht).


s.o. ohne Sortieren hilft es nicht. Programme zum Vergleichen von Textdateien gibt es wie Sand am Meer, ich bevorzuge BeyondCompare.

twm


Gahero - So 12.10.08 14:48

Hallo,
ich bins nochmal.
Ich glaube ich habe noch einen Fehler gefunden.
Kann es sein, dass es manchmal vorkommt, dass ein vorhandener Eintrag nicht richtig ausgelesen wird?

Ich benutze in meinem Programm mehrmals folgenden Code, natürlich mit anderen Eintragsnamen:

Delphi-Quelltext
1:
Frm.Com_Gamesettings_Vegetation_Quality.ItemIndex := ini_useroptions.ReadInteger('VegetationQuality');                    


Allerdings kommt es manchmal vor, dass immer wieder dieselben Aufrufe bestimmter Eintragsnamen eine 0 zurückliefern, obwohl die entsprechenden Einträge in der ini existieren und einen von 0 verschiedenen Wert besitzen und die anderen Werte korrekt ausgelesen werden. Seltsam ist, dass es immer nur dieselben Einträge sind, bei denen dies geschieht.

Folgende Zeilen sind betroffen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
// Texture Quality
ini_useroptions.WriteInteger('TextureQuality', Frm.Com_Gamesettings_Textures_Quality.ItemIndex + 1);   

// Shadow Quality
ini_useroptions.WriteInteger('ShadowQuality', Frm.Com_Gamesettings_Shadow_Quality.ItemIndex);

// Vegetation Quality
ini_useroptions.WriteInteger('VegetationQuality', Frm.Com_Gamesettings_Vegetation_Quality.ItemIndex);


Wie schon gesagt, sind es nur diese Zeilen während folgende Zeilen den Fehler noch nie hatten:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
ini_useroptions.WriteString('Resolution.Width', Frm.Edi_Gamesettings_General_ResolutionWidth.Text);

ini_useroptions.WriteString('Resolution.Height', Frm.Edi_Gamesettings_General_ResolutionHeight.Text);

ini_useroptions.WriteString('Resolution.RefreshRate', Frm.Edi_Gamesettings_General_ResolutionRate.Text);

ini_useroptions.WriteInteger('Speaker', Frm.Com_Gamesettings_General_Sound.ItemIndex + 1);

// Texture Shader
ini_useroptions.WriteString('ShaderQuality', Frm.Com_Gamesettings_Textures_Shader.Text);

// Texture Filtering
ini_useroptions.WriteInteger('TextureFilter', Frm.Com_Gamesettings_Textures_Filtering.ItemIndex);


Also müsste der Fehler in der Unit von dir liegen, ich hoffe du kannst da was machen... (Oder irgendjmd sonst hier hat eine Idee?)

Bis dann,
GaHero

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


Silas - So 12.10.08 17:10

Hi Gahero,

sieht aus, als würde ich doch noch mal aus dem .NET-Paradies zurückkehren :)

Der Fehler kommt mir irgendwie eigenartig vor, vor allem, weil ja alle Werte gleich ausgelesen/geschrieben werden... Vielleicht hast du irgendwo einen Schreibfehler bei einem Sektionsnamen (Groß/Kleinschreibung)? Ansonsten bin ich jetzt leicht überfragt, mir ist sowas noch nie passiert; vielleicht kann ich dir weiterhelfen, wenn du mir Unit & Ini schickst.

Grüße
Silas


Gahero - So 12.10.08 17:58

Ja, ich bin mittlerweile auch bei Net angekommen (ach ich liebe c sharp und visual studio), aber ich habe keine Lust die Anwendung nach Net umzuschreiben, da frag ich lieber dich, ob du da was machen kannst...^^

Hier die beiden Dateien... Wenn du noch was brauchst, sag bescheid!


Gahero - Sa 25.10.08 18:24

Und gibts was neues zu meinen Problem???


TDS - Do 26.03.09 23:15

Hallo @ all :-)

Gibt es denn noch irgendwo eine Möglich für den Download?
silas-online.de (hosted von bplaced.net) ist leider offline :-(


glotzer - So 12.04.09 18:29

hab das selbe problem, und ich würd die fastinis schon gern verwenden :)


TDS - So 12.04.09 19:55

user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
hab das selbe problem, und ich würd die fastinis schon gern verwenden :)

Hab mal einen Mirror online gestellt soweit ich das aus dem Google Cache holen konnte...
http://home.arcor.de/smartprog4u/


glotzer - So 12.04.09 19:57

tausend dank


himitsu - So 22.11.09 15:34

Mein Fazit zu dieser Klasse:

Solange wie der Ersteller diese nicht grundlegend überholt, ist sie absolut nicht empfehlenswert.

- das Chaos in den Destruktoren (Free ist kein Destructor)
- die Speicherlecks (fast keines der erstellen Objekte wird jemals freigegeben
- ab Delphi 2009 funktioniert keiner seiner ASM-Codes mehr,
da alles auf String/PChar/Char ausgelegt ist, was ab da ja wohl Unicode sein wird
und die ASM-Codes nur auf ANSI laufen. (wenn er wenigstens AnsiString/PAnsiChar und AnsiChar genommen hätte)

Quelle + genauere Gründe:
Delphi-PRAXiS > FastIniFiles Memory Leaks [http://www.delphipraxis.net/topic169018.html]


himitsu - So 22.11.09 19:38

- hoffentlich alle Speicherlecks behoben
- nebenbei unicodetauglich gemacht

bezüglich des Unicodes: entweder die INI ist schon Unicode oder man stellt ini.Unicode um

Wehe einer sagt was *speziell bestimmte DPler anguck*
und ja, ich weiß daß ich verrückt bin :nut:


TDS - Mo 23.11.09 09:38

user profile iconhimitsu hat folgendes geschrieben Zum zitierten Posting springen:
- hoffentlich alle Speicherlecks behoben
- nebenbei unicodetauglich gemacht

bezüglich des Unicodes: entweder die INI ist schon Unicode oder man stellt ini.Unicode um

Wehe einer sagt was *speziell bestimmte DPler anguck*
und ja, ich weiß daß ich verrückt bin :nut:

So, es wurde gerade alles auf den aktuellen Stand gebracht und erstmal hochgeladen.
http://home.arcor.de/smartprog4u/ ist up2date.


himitsu - Mo 23.11.09 11:45

Ein anderer User (API) hatte sich die Mühe gemacht und das Ganze einer gewissen Style-Guide-Anpassung unterzogen ... also Vieles etwas umformatiert.

Hab die Änderungen im vorhergehenden Post mit einfließen lassen.

[edit]
In der ZIP wurde nun auch die Dokumentation.html um die isUnicode-Eigenschaft erweitert.