Autor |
Beitrag |
Silas
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Fr 31.08.07 16:21
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:- Es können auch größere Dateien ohne extrem hohen Zeitverbrauch verwendet werden (bis zu 100 mal schneller als TMemIniFile!)
- Es lässt sich feststellen, ob die geöffnete Datei fehlerfrei war
- Es gibt die Möglichkeit, die Datei in einem anderen Ordner / mit einem anderen Dateinamen zu speichern
- FastIniFiles besitzt mehr Möglichkeiten, Daten zu speichern (z.B. Binärdaten)
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; if ValueExists('testValue') then WriteLn('testValue: ' + ReadString) 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.
Einloggen, um Attachments anzusehen!
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
Zuletzt bearbeitet von Silas am Fr 08.05.09 14:42, insgesamt 31-mal bearbeitet
|
|
Gausi
Beiträge: 8538
Erhaltene Danke: 475
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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?
_________________ We are, we were and will not be.
|
|
Silas
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Fr 31.08.07 17:03
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).
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Horst_H
Beiträge: 1653
Erhaltene Danke: 243
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: 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.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
matze
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: 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
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|
Silas
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: So 02.09.07 12:28
BenBE hat folgendes geschrieben: | Ist das Kommentar-Zeichen einstellbar? |
Ab jetzt schon. (Der Konstruktor hat einen zweiten Parameter bekommen)
BenBE 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.
BenBE 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).
BenBE 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.
BenBE hat folgendes geschrieben: | Kennst Du TBigIniFile? |
Nein (Hab auf die Schnelle jetzt auch nichts gefunden)
BenBE hat folgendes geschrieben: | Kann deine Klasse TColor-Werte lesen? |
Ist das nicht ein Integer?
BenBE 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.
matze 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.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
Zuletzt bearbeitet von Silas am So 17.02.08 16:55, insgesamt 1-mal bearbeitet
|
|
Silas
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: 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.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
Zuletzt bearbeitet von Silas am Sa 29.03.08 15:44, insgesamt 1-mal bearbeitet
|
|
Silas
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: 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.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
Zuletzt bearbeitet von Silas am Sa 29.03.08 15:44, insgesamt 1-mal bearbeitet
|
|
Gahero
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 05.02.08 16:22
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Heiko
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: 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?
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Heiko
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: 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?
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Heiko
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 12.02.08 21:16
Silas 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).
Silas 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.
Silas 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 12.02.08 22:56
Heiko 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, die du gemeint hast?
Heiko hat folgendes geschrieben: | Silas 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 .
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Heiko
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mi 13.02.08 08:12
Silas hat folgendes geschrieben: | Oder war es gar nicht die, 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.
Silas 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
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mi 13.02.08 17:23
Heiko hat folgendes geschrieben: | Silas hat folgendes geschrieben: | Oder war es gar nicht die, 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?
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
|