Eigendes Dateiformat



  • Hallo,
    ich weiß das klingt ein bisschen doof aber ich möchte mein eigenes binäres Dateiformat erstellen. Aber wie schiebt man die Informationen nach vorne?

    z.B.:

    struct info
    {
         int version;
    };
    

    version ist ja nicht gleich in den ersten Bytes (bzw. Bits), oder?

    LG



  • iKnow schrieb:

    Aber wie schiebt man die Informationen nach vorne?
    version ist ja nicht gleich in den ersten Bytes (bzw. Bits), oder?

    Wie meinst du ?
    Du solltest nicht einfach eine struct in die Datei schreiben, weil das keine gute Portabilität bietet.

    Du schreibst ganz einfach alle Informationen einzeln in die Datei.

    Pseudocode:

    struct structItem
    {
        int number;
        string name;
        short index;
    }
    
    struct structInfo 
    { 
         int version;
         array<structItem> items;
    
    }
    
    write(structInfo info)
    {
        file = openFile()
        file.writeInt(info.version)
        file.writeInt(info.items.count()) //number of items
        foreach(item in info.items)
        {
            file.writeInt(item.number)
            file.writeString(item.name)
            file.writeShort(item.index)
        }
    }
    


  • iKnow schrieb:

    version ist ja nicht gleich in den ersten Bytes (bzw. Bits), oder?

    Üblicherweise schon. Genauso wie im Speicher.



  • DarkShadow44 schrieb:

    Du solltest nicht einfach eine struct in die Datei schreiben, weil das keine gute Portabilität bietet.

    Wieso?



  • Swordfish schrieb:

    DarkShadow44 schrieb:

    Du solltest nicht einfach eine struct in die Datei schreiben, weil das keine gute Portabilität bietet.

    Wieso?

    Zum Beispiel weil verschiedene Systeme verschiedene Alignments/Padding Bytes haben könnten.



  • Swordfish schrieb:

    DarkShadow44 schrieb:

    Du solltest nicht einfach eine struct in die Datei schreiben, weil das keine gute Portabilität bietet.

    Wieso?

    Wieso sollte es? Word Size, Alignment, Bitrepräsentation, etc. So gut alles ist plattfishabhängig.



  • Ich wollte, dass er's hinschreibt, doofisch ...



  • Was ist ein "Eigendes Dateiformat"? 🤡



  • Wenns C++ kannst du der Struktur Funktionen geben, die dafür sorgen, dass die Daten aus einem Bytearray gelesen und wieder in eines geschrieben werden können.
    Bei C funktioniert gleich, nur dass die Funktionen als ersten Parameter einen Pointer auf die Struktur bekommen.

    int ist weniger ideal, da plattformspezifisch. Nimm lieber Typen mit expliziter Speichergröße, z.B. uint32_t für einen 4 byte unsigned integer.

    Idealerweise kapselt man das Bytearray noch in eine Klasse, sodass immer Längenchecks gemacht werden können. Bei der Zeigervariante wie unten gezeigt könnte man über die Grenzen rausschreiben.

    // erweitere Struktur
    struct info
    {
         uint32_t version; // 4byte
         uint16_t weitereDaten; // 2byte
    
         void ToByteArray(char* data) const;
         void FromByteArray(const char* data);
         size_t GetByteSize()const {return 4+2;}
    };
    
    // Verwendung
    // Struktur mit Daten befüllen
    info anInfo;
    anInfo.version=5;
    anInfo.weitereDaten=99;
    
    // Bytearray anlegen (am besten eigene Klasse dafür bauen), Struktur kopiert sich selbst ins Bytearray
    std::vector<char> bytearray(anInfo.GetByteSize(),0);
    anInfo.ToByteArray(&bytearray[0]);
    
    // jetzt musst du nur noch das Bytearray 1:1 in eine Datei schreiben, dafür gibts den Binärmodus der Dateifunktionen
    ...
    


  • hgfhfghfhfhf schrieb:

    Nimm lieber Typen mit expliziter Speichergröße, z.B. uint32_t für einen 4 byte unsigned integer.

    Inwiefern ist das besser? Hängt immer noch von Komplement, Endian, Padding etc. ab.



  • doofisch schrieb:

    hgfhfghfhfhf schrieb:

    Nimm lieber Typen mit expliziter Speichergröße, z.B. uint32_t für einen 4 byte unsigned integer.

    Inwiefern ist das besser? Hängt immer noch von Komplement, Endian, Padding etc. ab.

    Die Größe ist dann fix.
    Die Funktion void ToByteArray(char* data) const kümmert sich um den Rest.
    Padding gibts im Dateiformat keines mehr. Bytereihenfolge wird natürlich entsprechend angepasst. Ein uint32_t wird in einzelne Bytes zerlegt, Bytes werden umsortiert (siehe Funktionen wie htons, die shiften die Bytes einfach in die richtige Reihenfolge), und erst die werden ins Bytearray geschrieben.
    Komplement interessiert bei unsigned ohnehin nicht.


Anmelden zum Antworten