>>-Operator bei Binärdateien



  • Hallo,
    ich schreibe momentan an einem Programm, welches ein spezielles Binärformat auslesen soll. Nun geht es um das Auslesen von long- und float-Werten usw.
    Da man anscheinend mit dem >>-Operator keinen long-(und vermutlich auch keinen float-)Wert aus einer Binärdatei "ziehen" kann, habe ich mir eine kleine Templatefunktion geschrieben:

    template<typename T>
    inline T readValue(std::fstream &fstream, bool byteSwap = false)
    {
    	char bytes[sizeof(T)];
    	fstream.read(bytes, sizeof(T));
    	T result = 0;
    
    	if (byteSwap)
    	{
    		for (int i = sizeof(T) - 1; i >= 0; --i)
    			result |= (bytes[i] << (i << 3));
    	}
    	else
    	{
    		int j =  sizeof(T) - 1;
    
    		for (int i = 0; i < sizeof(T); ++i, --j)
    			result |= (bytes[i] << (j << 3));
    	}
    
    	return result;
    }
    

    Die scheint auch ganz gut zu funktionieren und kann mit little und big endian umgehen, was für mein tolles Format von Nöten ist.
    Allerdings würde ich jetzt gerne wissen, ob es nicht doch einen einfacheren oder besseren Weg über die Standardbibliothek gibt bzw. tue ich mich jetzt bei floats recht schwer, da nicht direkt spezifiziert ist, wie diese binär gespeichert werden.


  • Mod

    Barade schrieb:

    Allerdings würde ich jetzt gerne wissen, ob es nicht doch einen einfacheren oder besseren Weg über die Standardbibliothek gibt bzw. tue ich mich jetzt bei floats recht schwer, da nicht direkt spezifiziert ist, wie diese binär gespeichert werden.

    Ja: Klartext

    edit: Betonungen in der Frage durch mich gesetzt



  • Klartext? Hmm, also wenns in der Standardbibliothek nicht gescheit funktioniert, dann würde ich mich halt nach was anderem plattformübergreifenden umsehen.
    Gibt's nicht z. B. in der boost-Bibliothek oder so schon vordefinierte Stream-Funktionen, bei denen man eventuell noch spezifizieren kann, ob's big oder little endian-Werte sind?

    Es gibt auch eine ASCII-Version des Formats, sprich für Menschen lesbar, aber ich möchte gerne beide unterstützen.
    Da es sich dabei um ein 3d-Modell-Format handelt, nehme ich mal an, dass man das aus Geschwindigkeitsgründen so entworfen hat.

    edit:
    Also mit diesem lustigen Konstrukt

    fstream.read((char*)&this->m_version, sizeof(this->m_version));
    

    scheint es wohl auch zu klappen, anscheinend sogar bei Fließkommazahlen.



  • Man kann das auch angenehmer schreiben. Ich nehme an, du hast keinen Grund, hier this zu benutzen?

    fstream.read(reinterpret_cast<char*>(&m_version), sizeof(m_version));
    


  • guck' mal hier und hier und frag' nach, wenn was nicht klar ist.

    Ein Plattform übergreifendes (Standard)Binärformat existiert nicht. Das geht bei Big/Little-Endian los und hört bei IEEE 754 noch nicht auf.



  • Danke für die Antworten.
    Werde mir das mit einer abgeleiteten Stream- und einer eigenen Binärklasse mal noch überlegen, da es ja jetzt auch so zu funktionieren scheint (ohne meine Templatefunktion).



  • Wo ist denn das Problem? Wenn du von Stelle x ein float lesen willst, leg eine float Variable an, lese 4 Bytes von der Datei ein (an Stelle x) und kopier die 4 Bytes auf die Variable. Fertig.



  • Icematix schrieb:

    Wo ist denn das Problem? Wenn du von Stelle x ein float lesen willst, leg eine float Variable an, lese 4 Bytes von der Datei ein (an Stelle x) und kopier die 4 Bytes auf die Variable. Fertig.

    eben nicht.


Anmelden zum Antworten