Entwickler-Ecke

Dateizugriff - Effizient Daten in Dateien speicern


Geisterbär - Do 13.02.03 02:16
Titel: Effizient Daten in Dateien speicern
Ich habe nun eine Frage an die schlaue Köpfe hier....

Wie speichere ich effizient Daten in Dateien und wie lese ich sie aus ?

Es geht um Listen von bestimmten daten, deren Format vorher bestimmt ist.


AndyB - Do 13.02.03 08:07

Wenn die Datei wie eine Datenbank aufgebaut ist, jeder Datensatz gleich lang ist, so ist der Zugiff über typisierte Dateien der leichteste.
Trifft dies jedoch nicht zu, so gibt es mehrere Möglichkeiten:
TFileStream, file of Byte, Memory Mapped Files.


Klabautermann - Do 13.02.03 11:50

Hallo,

der Schnellste zugriff dürfte der Untypisierte sein (Delphi-Hilfe: Untypisierte Dateien ; FILE ; BlockRead ; Blockwrite ...). File-Streams sind sehr ähnlich und sollten intern auch nicht so viel anders arbeiten (habe ich nicht überprüft) also auch ähnliche geschwindigkeiten liefern.
Typisierte-Dateien sind aber für dich als Programmierer weniger aufwändig und sollten auch noch eine anständige Performance bieten.
Bei beiden Systemen solltest du aber auf jeden Fall dran denken, eine Versionskontrolle mit einzubauen, damit du nicht vor Problemen stehst, wenn sich die Daten einmal ändern.

Gruß
Klabautermann


Dargor - Do 13.02.03 14:20

Ich habe zum Speichern von Dateen positive Erfahrung mit INI-Dateien gemacht: Einfach zu handhaben und kleinere Größe der Datei als z.B. eine typisierte Datei.
Weiterer Vorteil: Beim Speichern von Strings ist die Länge des Strings bei INI-Dateien relativ egal (afaik max. 255), bei typ. Dateien muß eine feste Größe (z.B. file of string[30]) angegeben werden.


Udontknow - Do 13.02.03 14:53

Naja, also kleiner wirds in einer Inidatei nicht. Wenn du 100 Integer-Variablen mit 7 Stellen abspeicherst, verbrauchst du wenigstens 11 Byte pro Variable (2 Byte Bezeichner,1Byte =, 7 Byte Ziffern,1Byte Zeilenumbruch). Sonst brauchst du immer nur 4 Byte.

Cu,
Udontknow


Klabautermann - Do 13.02.03 15:01

Außerdem sind INI-Dateien verhältnismäzig langsam, da sie 1. recht groß sind und 2. aufrund der Stuktur in der regel Komplett oder zu großen teilen (ich habe nicht überprüft wie es verwirklicht wurde) neu geschrieben werden müssen wenn gespeichert wird.

Gruß
Klabautermann


maximus - Do 13.02.03 15:46

Ausserdem müssen ini-files immer geparsed (auseinanderklabüstert ) werden. 8)


DaRkFiRe - Do 13.02.03 17:13

Ich hab mal gelesen, dass INIs max. 64kb groß sein können - ich kann mich täuschen, aber ich glaube es mal gelesen zu haben!


Klabautermann - Do 13.02.03 17:23

Hallo,
DaRkFiRe hat folgendes geschrieben:
Ich hab mal gelesen, dass INIs max. 64kb groß sein können - ich kann mich täuschen, aber ich glaube es mal gelesen zu haben!

das trifft auf tIniFile zu, wenn du tMemINIFile verwendest können die Dateien wesentlich größer sein.
Ein entsprechendes Beispielprogramm habe ich vor einer kleinen Ewigkeit mal für ein entsprechendes Topic geschrieben. Du kannst es in meinen Delphi Samples [http://downloads.oitmann.de/samples] finden.
@Geisterbär: Dabei fällt mir ein, da gibt es auch ein Beispielprogramm zu Typisierten Datein.

Gruß
Klabautermann


DaRkFiRe - Do 13.02.03 20:33

THX, Klab!

Wieder schlauer *g*


Dargor - Fr 14.02.03 03:30

Ein Vergleich:

a) Mit typisierter Datei (file of string[62]) wurden 1000 Strings mit 10-62 Zeichen Länge gespeichert:
Ergebnis: eine Datei mit 620 kb Größe

b) Mit einer IniDatei wurden ebenfalls die gleichen Strings abgespeichert:
Ergebnis: eine Datei mit 15 kb Größe

Große Preisfrage: Welche Datei ist nun größer?


DaRkFiRe - Fr 14.02.03 03:52

c)

es werden 1000 Strings mit je max. (!) 62 Zeichen gespeichert.

Da 62 in ein Byte (255) passt, kann man also sagen:
1 Byte + String (nicht mit max. Länge, sondern mit tatsächlicher Länge!)

Pro Datensatz:

minimalst: 1 Byte (Länge des Strings: 0)
maximal: 63 Byte (Länge des Strings: 62; + 1 Byte (länge des Strings))

Datei mit 1000 Sätzen ( ohne Header o.ä. ):

minimale Dateigröße: 1.000 Byte
maximale Dateigröße: 63.000 Byte

Hm!? :?: :idea:


Ach ja: macht man jetzt ein Zahlenspielchen und vergrößert die Stringlänge auf 255 Zeichen, dann sieht das folgendermaßen aus:

Das Längenbyte bleibt

1 Datensatz:
minimal: 1 Byte
maximal: 255 Bytes

1000 Datensätze:
minimal: 1000 Byte
maximal: 255.000 Byte (grübel)


Ach ja: macht man das nun mit variablen Strings (also die ANSI-Strings bis knapp 4 GB (2^32-1 Byte) ), dann sieht das so aus:

1 Datensatz (!!!):
minimal: 4 Byte (4*8 = 32; 32 Bit -> 4 GB)
maximal: 2^32-1 Bytes + 4 Byte (4.294.967.299 Bytes)

1000 Datensätze (!!!):
minimal: 4000 Byte
maximal: 1000*(2^32-1 Bytes + 4 Byte) (4.294.967.299.000 Bytes)

Hier wird deutlich: mit typisierten Dateien kann man nur bei fixen Variablentypen arbeiten (z.B. extended / single, integer / word / byte usw.) - für Strings rate ich davon ab.

Also solche Art Speicherung von Strings bevorzuge ich... Wer möchte nen Quelltext!? *g* Bin zu müde, den JETZT zu posten.


Klabautermann - Fr 14.02.03 12:25

Hallo,
Dargor hat folgendes geschrieben:
Große Preisfrage: Welche Datei ist nun größer?

Das ist aber ein entsprechend konstruiertes Beispiel.

1. Es ist Richtig das Typisierte Dateien mit Blöcken Arbeitet. D.h. für jeden Datensatz wird die Maximale größe belegt, auch wenn diese nicht ausgefüllt wird (wie bei kürzeren Strings). Ini Dateien speichern hingegen nur Tatsächliche Daten.

2. In Typisierten Dateien werden Zahöen auch als solche Abgelegt, ein LongInt ist also immer 4Byte groß, egal welcher Wert drinsteht. In einer INI-Datei werden die Daten immer als String gespeichert. Eine sechstellige Zahl belegt also auch 6 Byte, eine einstellige hingegen nur eins.

3. Zusätzlich zu den Nutzdaten werden in einer INI auch recht speicherintensive Verwaltungsinformationen gespeichet. Dies sind die Rubrikbezeichnungen, die Schlüssel und die dazugehörigen Begrenzungszeichen ([,],=).

4. Der Record bei Typisierten Dateien sollte immer mit dem Schlüsselwort Packed versehen werden um auf größe Optimiert gespeichert zu werden.

5. Angenommen eine Datei hat 50.000 Einträge, der Zweite soll geändert werden.
a) Die Datei ist eine Typisierte Datei:
Die Daten werden an der entprechenden Stelle der Festplatte manipuliert. Die Struktur wird dadurch nicht verändert, da ja bereits ein Block mit der Maximalen Größe Existiert.
b) Die Datei ist eine INI.Datei:
Durch die Änderung der Daten verschiebt sich die Datenstruktur (denn die neuen Daten können ja länger oder kürzer sein) also muss die Datei ab dem zweiten Datensatz komplett neu geschrieben werden. Das ist wesentlich Resourcenaufwändiger.

6. Beim auslesen einer Typisierten Datei muss lediglich eine Feste Anzahl vom Bytes in eine Variable gleicher Größe Kopiert werden. Mit dieser Variable kann dann wie gewohnt gearbeitet werden.
Beim auslesen einer INI-Datei muss erst ein unter umständen lander Text durchsucht und Interpretiert (geparst) werden. Danach folgt unter umständen noch ein Typecasting um den dort gefundenen String in einen anderen Datentyp zu Konvertieren. Auch dies ist verhältnismäßig Recourcenaufwändig.

Ich will dier deine INI-Datei gar nicht Madig machen. Ich verwende sie auch gerne. Aber effizient sind diese nun wirklich nicht. Sie sind nur unheimlich Konfortabel (so kann man hier häufig auf eine Versionskontrolle komplett verzichten).

Gruß
Klabautermann


1Stein - So 16.02.03 01:33

Da ich bei euerem wirwar net durchblicke frage ich einfach mal Wie Speichert man daten in Dateien und wie ruft man sie ab und speichert sie in einer Varialble innerhalbt des progs bzw gibt sie in einem Label aus? :?: :?: :?: :?: :?: :?:


Tino - So 16.02.03 12:58

Wie wäre es wenn Du das Topic noch mal durchliest und die Fragen die Du dann noch hast hier einfach mal stellst!

Gruß
TINO