binär-daten in dateien speichern



  • hiho,

    ein kleine frage dazu, wie man binäre daten in dateien speichert. also ich habe viele bytes im wertebereich von 0-255, die ich gerne auf der festplatte ablegen möchte und zu einem späteren zeitpunkt wieder lesen möchte. der inhalt soll hierbei selbstverständlich unverändert bleiben. das problem hierbei ist, dass sowohl ifstream als auch ofstream mit char funktionieren. der wertebereich von char ist leider gottes implementierungsabhängig. trotzdem reicht char ja auf den gängigen plattformen von -128 bis 127. was ist ein portabler weg, wie ich meine bytes (von 0-255) in einer datei ablegen und wieder auslesen kann?

    lg

    ps: ist der ausdruck static_cast<char>(0xFF) überhaupt definiert, wenn std::numeric_limits<char>::max() == 0x7F ?



  • alskfjlsödk schrieb:

    der wertebereich von char ist leider gottes implementierungsabhängig.

    Jo. Aber du hast noch signed/unsigned.


  • Mod

    Binärdaten sind ja gerade nicht portabel, daher: Gar nicht, außer du sagst halt, dass das Binärformat eines bestimmten Systems das einzig wahre Format ist. Dann kannst du auf diesen Systemen einfach ganz naiv schreiben und lesen und auf Systemen, die dazu nicht kompatibel sind, musst du entsprechend konvertieren.

    PS: Signed-Überläufe sind (bewusst) undefiniertes Verhalten.



  • reissman schrieb:

    alskfjlsödk schrieb:

    der wertebereich von char ist leider gottes implementierungsabhängig.

    Jo. Aber du hast noch signed/unsigned.

    std::ofstream::char_type ist aber char, nicht signed/unsigned.

    SeppJ schrieb:

    Binärdaten sind ja gerade nicht portabel, daher: Gar nicht, außer du sagst halt, dass das Binärformat eines bestimmten Systems das einzig wahre Format ist. Dann kannst du auf diesen Systemen einfach ganz naiv schreiben und lesen und auf Systemen, die drazu nicht kompatibel sind, musst du entsprechend konvertieren.

    wenn du hiermit auf endianness, 2s complement etc. anspielst: dessen bin ich mir durchaus bewusst.
    wie eingangs erwähnt geht es mir aber lediglich darum, eine kette an bytes (unsigned chars, wenn man so will) in eine datei zu schreiben und später wieder zu lesen. und ist das wirklich nicht portabel möglich? denn das ist ja wohl in so ziemlich jedem heutigen computerprogramm so vorzufinden.

    SeppJ schrieb:

    PS: Signed-Überläufe sind (bewusst) undefiniertes Verhalten.

    sind sie nicht implementierungsabhängig?



  • std::ofstream::char_type ist aber char, nicht signed/unsigned.

    Wie wärs mit basic_ofstream<unsigned char> ?


  • Mod

    alskfjlsödk schrieb:

    SeppJ schrieb:

    Binärdaten sind ja gerade nicht portabel, daher: Gar nicht, außer du sagst halt, dass das Binärformat eines bestimmten Systems das einzig wahre Format ist. Dann kannst du auf diesen Systemen einfach ganz naiv schreiben und lesen und auf Systemen, die drazu nicht kompatibel sind, musst du entsprechend konvertieren.

    wenn du hiermit auf endianness, 2s complement etc. anspielst: dessen bin ich mir durchaus bewusst.
    wie eingangs erwähnt geht es mir aber lediglich darum, eine kette an bytes (unsigned chars, wenn man so will) in eine datei zu schreiben und später wieder zu lesen. und ist das wirklich nicht portabel möglich? denn das ist ja wohl in so ziemlich jedem heutigen computerprogramm so vorzufinden.

    Ein Byte hat nicht unbedingt 8 Bit. Wenn ein System mit 8-Bit Bytes schreibt und ein anderes System mit 48-Bit Bytes liest, dann ist auch ein solch einfaches Binärformat selbstverständlich nicht kompatibel, ohne Konvertierungen vorzunehmen. Da du nach den theoretischen Grenzen der Portabilität gefragt hast, habe ich da auch solche Fälle mit betrachtet, obwohl dir wahrscheinlich niemals im Leben ein Computer mit anderer Bytegröße als 8 Bit begegnen wird.
    So lange du nur 8-Bit System vorliegen hast, wird es natürlich funktionieren, das ist ja gerade das Verfahren, das ich beschrieben habe.

    SeppJ schrieb:

    PS: Signed-Überläufe sind (bewusst) undefiniertes Verhalten.

    sind sie nicht implementierungsabhängig?

    Nein. Der Sinn der Sache ist das Ermöglichen gewisser Optimierungen, die in Grenzfällen zu Verhalten führen könnten, das man bei einem definierten Überlauf nicht hätte. Beispielsweise kann man

    int summe = 0;
    for(int i = start; i != ende; ++i)
      summe += i;
    

    mittels Summenformel extrem optimieren, aber nur wenn start <= ende, man also keinen Überlauf hat. Daher definiert man den Sonderfall des Überlaufs zu undefiniertem Verhalten, um den Normalfall besser optimieren zu können.



  • Mit den Datentypen int8_t bzw. uint8_t aus cstdint bist du immer auf der richtigen Seite. Endianess kann noch eine Rolle spielen.


Log in to reply