gepufferter Dateizugriff
-
Ich bin mir sicher, dass es eine fertige Lösung zu folgendem Problem gibt, aber ich finde sie gerade nicht:
Ich möchte Daten aus großen Files lesen und schreiben.
Am liebsten würde ich die gesamte Datei in einen C-Array oder einen Vector
laden und mit dem Arrayindex auf die Bytes einzeln zugreifen.
Bei Files, die größer als der Arbeitsspeicher sind (Größenordnung GB)
ist das keine gute Idee. Der Zugriff erfolgt mehr oder weniger lokal im File,
läuft aber nach und nach über das ganze File, mal vor mal wieder ein Stück
zurück. Natürlich kann kann ich mir selbst einen Buffer anlegen und den Teil,
den ich gerade bearbeiten will dort reinladen, wenn ich über die Grenzen hinaus
komme die Daten wieder zurück ins File schreiben und den nächsten Block
nachladen. Aber so etwas müsste es doch auch schon fertig geben.Ich suche also eine Klasse, die sozusagen Vector und fstream vereinigt:
Ich initialisiere die Klasse mit einem Filenamen oder Filepointer, weise
einen Buffer oder eine Buffergröße zu und der Buffer wird angelegt und dann
kann ich mit der Klasse arbeiten wie mit einem Vector. Elemente, die gerade
nicht im Speicher sind, werden nachgeladen und zuvor ggf. geänderte Daten
ins File geschrieben. Zugriffe auf das File sollen blockweise geschehen,
und zwar immer nur dann, wenn die jeweils angesprochene Fileposition gerade
nicht im Speicher ist. Ich möchte eben aus Performance-Gründen nicht bei
jedem Zugriff ein fseek aufrufen und dabei Zugriff auf jede beliebige
Position im File haben.
-
Dann solltest du mal bei deinem Betriebssystem nach Funktionen für 'File Mapping' Ausschau halten.
http://en.wikipedia.org/wiki/Memory-mapped_file
-
danke, das hilft bei der Performance-Frage weiter. Aber wenn ich das recht
verstehe, muss man als Programmierer immer noch den richtigen Bereich aus
dem File mappen und die File-Position relativ zum ersten gemappten Byte angeben,
beim Überschreiten der Arraygrenzen den Bereich wieder mit unmmap freigeben,
einen anderen Bereich dafür wieder mappen (wenn man nicht das gesamte File
in den Speicher laden kann).Mit fstream::rdbuf scheint mir das gleiche Problem vorzuliegen. Auch da sind
die Adressen auf den Buffer bezogen und nicht auf die Position im File.Ich hätte gerne eine Klasse, für die der []-Operator überladen ist, so dass man
dort die Position innerhalb des Files angeben kann und der Operator greift intern
auf den Buffer zu, falls diese Position im Buffer ist, andernfalls wird der
Bufferinhalt bei Bedarf ins File geschrieben und ein anderer Bereich geladen, der
die Adresse enthält.