Ideale Speichermethode gesucht
-
EDIT: Ups wahrscheinlich falsches Forum, vielleicht könnt ihr es mal bitte zur MFC verschieben... sorry

Hallo allerseits,
ich muss zugeben, ich bin gerade ein wenig verwirrt von der Vielfalt der Möglichkeiten, Daten in eine Datei zu speichern und kann mich so gar nicht entscheiden, welche Methode ich nun am besten wähle, die da am effizientesten sein kann.
Zu speichern sind bei mir Daten in der Form
long, CByteArrayEin CByteArray* wird von einem Objekt an eine die Speicherverwaltung beinhaltende Klasse übergeben. Das Array enthält alle wichtigen Daten. Der Longwert beschreibt die eindeutige ID des Objekts, dass Daten speichern möchte.
Bisher speicher ich alles nur in einer Map. Sozusagen wie in einer Tabelle.
typedef CTypedPtrMap < CMapWordToOb, long, CByteArray* > CMapLongToCByteArray; CMapLongToCByteArray m_map;Nun ist aber die Aufgabe, dass alles in eine Datei auszulagern. Und es soll jede Änderung sofort in die Datei einfließen. Sprich, die Objekte melden sich bei Wertänderung, schicken ein neues CByteArray und damit muss das alte überschrieben werden. Das Ganze ist für den Fall, falls das Programm oder sogar der Rechner abstürzen, können somit die vormals aktuellen Werte wieder hergestellt werden.
Klar wär dafür eine Datenbank am besten (wird es auch geben und ist wahrscheinlich am sinnvollsten), aber ich hab nun den Auftrag, die Möglichkeit zu schaffen, es auch in eine Datei auszulagern.
Mit Serialisierung hab ich bisher leider keine Erfahrung, daher weiß ich nicht, ob das in der Lage ist, auch Daten nur zu "updaten" oder ob das dann immer die gesamte CMap neu speichern würde. Das wäre dann definitiv zu langsam. Also muss ich mich wohl selbst darum kümmern.
Was denkt ihr, was da am schnellsten sein dürfte? Zeilenweise Ausgabe in einer Textdatei (analog einer Tabelle eben) oder vielleicht doch lieber eine Binärdatei? Ich weiß, dass die Datei höchstwahrscheinlich nach kurzer Zeit stark physisch fragmentiert sein dürfte, aber das ist erstmal nebensächlich.
-
Deine Möglichkeiten hängen ganz davon ab, wie sich die Objekte ändern können. Wenn dein CByteArray eine feste Größe hat, könntest du es einfach in der Datei überschreiben (per seekp() an die richtige Position fahren und per write() schreiben), wenn sich die Größe ändern könnte, bleibt dir nichts anderes übrig als die komplette Datei jedes Mal neu zu schreiben (bzw. zumindest alles nach der geänderten Position).
-
Tja voraussichtlich wird sich die Größe ändern. Kann man da rein logisch nicht irgendwas einfügen? Kümmert sich dann nicht das BS um den Rest (umkopieren usw)? Was da nun rein physisch auf dem Datenträger passiert, ist mir ja relativ egal.
-
Wenn du mit fstream-Methoden etwas in eine Datei schreibst, wird deren voriger Inhalt überschrieben - da kannst du physikalisch nichts dazwischenschieben oder zusammendrücken.
Wenn es dir nicht so sehr auf die Dateigröße ankommt, gäbe es noch eine Alternative: Du speicherst zunächst alle Map-Einträge mit fester Größe (jeweils ID, Größe des Arrays und Position des Arrays in der Datei) und danach die einzelnen Arrays (jeweils mit einigen Leerfeldern dahinter). Wenn das Array etwas wächst, kannst du die Leerfelder auffüllen, wenn du dort keinen Platz mehr hast, hängst du es ans Ende der Datei an und passt die Positions-Angabe in ersten Teil an.
(um die Datei nicht ins Uferlose wachsen lassen und mit Mülldaten zu füllen, kannst du in regelmäßigen Abständen die alte Datei wegschmeißen und von Grund auf neu schreiben)
-
Hm ich hatte gedacht, dass sowas das BS selbst verwalten könnte. Dort können ja physisch auch Dateien fragmentiert sein, obwohl sie logisch natürlich aus einem Guss sind.
Hatte gehofft, ich könnte wie bei einem Texteditor was einfügen, speichern sagen und fertig. Gibt's da noch keine Klassen für, die sowas können?
Ansonsten hab ich mir noch überlegt, zwischen den Objekten zu unterscheiden, ob sie nun CByteArrays mit gleich oder unterschiedlicher Größe übergeben. Die statischen können alle in dieselbe Datei und dort kann dann jeweils der alte Eintrag überschrieben werden, für die dynamischen Array könnte man pro Objekt eine Datei anlegen bzw. es in etwa so machen, wie du vorhin beschrieben hast. Bzw. könnte dann auch gleich jedes Objekt eine eigene Datei bekommen. Denn selbst wenn ich mehrere 1000 Objekte (und demzufolge auch Dateien haben sollte), dann würde es ja wahrscheinlich keinen Unterschied machen, ob ich nun viele kleine Dateien immer wieder öffne, schreibe, schließe oder eine große Datei öffne, parse, schreibe, schließe. Da ist das erste vielleicht sogar noch performanter oder?
-
Wenn du in einem Text-Editor etwas eingibst, wird das auch zunächst nur im Arbeitsspeicher zwischengelagert (dort hast du tatsächlich mehr und differenziertere Möglichkeiten, deine Daten zu fragmentieren) und erst beim Speichern (bzw. wenn er in regelmäßigen Abständen automatisch speichert) der komplette Dateiinhalt auf Disk geschrieben).
-
Hm stimmt ja, da wird ja auch immer das komplette File neu geschrieben

Hatte irgendwie gedacht, dass das Dateisystem auch irgendwie mit verketteten Listen arbeitet und daher ohne Probleme irgendwo mal ein Stück einfügen/rausreißen kann ohne alles andere neuschreiben zu müssen...
Na gut, dann hab ich das wohl irgendwie verrissen und mich wohl zu sehr auf diese Möglichkeit versteift.
Dann ist wahrscheinlich wirklich die Methode mit einer Datei je CByteArray am besten oder gibt's noch andere Vorschläge?