Blockweises Lesen und Schreiben von Dateien



  • Hallo zusammen,

    Dateien werden ja auf der Festplatte in Blöcken gespeichert.
    Jetzt möchte ich (vereinfacht gesagt) eine Datei mit folgender Struktur
    erstellen:

    Block 1: Index
    --------------
    Objekt 1 -> Block 2, Position 4
    Objekt 2 -> Block 4, Position 2
    Objekt 3 -> Block 3, Position 3
    ...
    Fortsetzung Index -> Block 5
    
    Block 2: Daten
    --------------
    Objekt a
    Objekt b
    Objekt c
    Objekt 1
    
    Block 3: Daten
    Block 4: Daten
    Block 5: Index
    ...
    

    Ich denke, es ist klar, wie ich mir das etwa vorstelle...

    Jetzt möchte ich ja, wenn ich ein Objekt verändere, nicht die komplette
    Datei neuschreiben. Dazu würde ich gerne den Block x auslesen und den Block
    y schreiben.

    Also generell Suche ich nach Funktionen wie:

    int getBlockSize(file f); // Größe eines Blockes auf der Festplatte, auf dem sich f befindet
    void writeBlock(file f, int pos, char* data); // Schreibe Daten data in Block pos von Datei f
    void readBlock(file f, int pos, char* data); // Lese Daten data von Block pos von Datei f
    int appendBlock(file f, char* data); // Hänge neuen Block mit Daten data ans Ende der Datei f an
    void removeLastBlock(file f); // Lösche letzten Block der Datei f
    

    Natürlich sollen die Funktionen nur die Aufgaben zeigen.

    Ich vermute mit der Standard-Library kommt man da nicht weiter.
    Gibt es von Boost oder so plattformunabhängige Funktionen?
    Falls nicht, lasse ich mich auch gerne ins Linux/Unix-Forum verschieben
    um mir dort passende Funktionen vorschlagen zu lassen. (Mac OS X 10.6.6)

    Ich bin für alle Anregungen dankbar.

    Gruß,
    XSpille



  • Bei boost::interprocess gibt es memory mapped files, womit man schön Objekte oder gar ganze STL Container in Dateien halten kann.



  • Danke brotbernd!

    An dem managed_mapped_file stört mich (ein wenig), dass es komplett im
    Speicher gehalten wird. Ich kuck mal, ob ich in boost::interprocess auch noch
    eine andere Möglichkeit gibt.

    The whole file is mapped in the process' address space.

    http://www.boost.org/doc/libs/1_46_0/doc/html/interprocess/managed_memory_segments.html#interprocess.managed_memory_segments.managed_mapped_files.constructing_managed_mapped_files



  • Ich glaube, ich werde mich mit der nativen C-Lösung pwrite/pread anfreunden:
    http://www.tutorialspoint.com/unix_system_calls/pwrite.htm

    Jetzt such ich nur noch nach einer Funktion, die mir die Blockgröße auf
    der Festplatte ermittelt...
    Falls jemand eine kennt, bin ich für einen Hinweis dankbar 🙂

    ➡ Ihr könnt mich jetzt auch ins Linux/Unix - Forum verschieben

    EDIT:
    Ich bin fündig geworden. fstat macht genau das, was ich suche 🙂
    http://www.tutorialspoint.com/unix_system_calls/fstat.htm



  • XSpille schrieb:

    Danke brotbernd!

    An dem managed_mapped_file stört mich (ein wenig), dass es komplett im
    Speicher gehalten wird. Ich kuck mal, ob ich in boost::interprocess auch noch
    eine andere Möglichkeit gibt.

    The whole file is mapped in the process' address space.

    http://www.boost.org/doc/libs/1_46_0/doc/html/interprocess/managed_memory_segments.html#interprocess.managed_memory_segments.managed_mapped_files.constructing_managed_mapped_files

    Die Datei wird gemapped, nicht kopiert! Es befindet sich also nicht unbedingt die ganze Datei im Hauptspeicher, sondern nur die gerade verwendeten Blöcke. Wird Platz für andere Programme benötigt, werden die Speicherblöcke sofort freigegeben. Insgesamt verbrauchst du eher weniger Speicher als mit herkömmlichen FILE-Funktionen. Bei großen Dateien auf einem 32-Bit System könnten dir allenfalls die Speicheradressen ausgehen, nicht aber der Speicher selbst.


Anmelden zum Antworten