BinaryReader, Fliesskomma Datenformat



  • Hallo Leute,

    ich versuche eine Binärdatei mit BinaryReader einzulesen. In dieser Datei befindet sich ein buntes Gemisch von Strings, Integer und Fliesskommazahlen.
    Ich möchte gleich darauf hinweisen dass das Dateiformat vor mindestens 20 Jahren festgelegt wurde.

    Beim Einlesen der Integer-Werte ist mir bereits aufgefallen, dass die beiden Bytes vertauscht sind. Man kann die Integer also nicht mit

    i = binaryReader->ReadInt16();
    

    einlesen, sondern muss stattdessen

    i = 256 * binaryReader->ReadByte();
    i += binaryReader->ReadByte();
    

    verwenden. Das funktioniert soweit (abgesehen vom Vorzeichen, aber das ist egal weil sowieso alle Zahlen positiv sind).

    Ein Problem stellen aber die Fliesskomma-Zahlen dar, bei denen offenbar ein anderes Format verwendet wird:
    3F 00 00 00 muss dem Wert 0.5 entsprechen
    35 29 DD AF muss dem Wert 6.328e-7 entsprechen
    Wenn ich versuche diese Zahlen mit

    f = binaryReader->ReadSingle();
    

    einzulesen, kommt dabei nur Unsinn heraus.
    Wie kann man dieses Zahlenformat in ein Single konvertieren?

    Zweite Frage:

    In der Datei befinden sich auch Null-terminierte Strings. Für jeden String ist in der Datei eine festgelegte Anzahl von Bytes vorgesehen. Der String kann aber auch kürzer sein, in diesem Fall sind die restlichen Bytes mit Nullen aufgefüllt. Es ist wichtig dass ich genau die richtige Anzahl von Bytes einlese, dann dahinter folgen ja noch weitere Daten. Vorläufig lese ich den String in ein Byte-Array ein und ignoriere dessen Inhalt:

    array<Byte> ^buf; 
    buf = gcnew array<Byte>(5000);
    binaryReader->Read(buf,0,40);
    

    Wie kann ich jetzt den Inhalt des Byte-Arrays in einen String konvertieren?

    Gruß
    Michael



  • Hallo micha7,

    ich denke, das Problem ist generell einfach LittleEndian versus BigEndian.

    Du müßtest einfach die Daten in ein Byte-Array einlesen (so wie du es ja auch schon für die Strings machst), dann Array.Reverse() aufrufen und dann mittels der BitConverter-Klasse dann den Single-Wert lesen: BitConverter.ToSingle(...).

    Und um aus einem Byte-Array einen String zu erzeugen gibt es die Encoding-Klasse:
    Encoding.ASCII.GetString(...). (Je nach Encoding mußt du die passende Eigenschaft benutzen: ASCII, Default, UTF8, UTF7, ... oder aber die CodePage im Konstruktor bzw. mit Encoding.GetEncoding() selber festlegen).



  • Hallo,

    danke, hat beides funktioniert !

    Gruß
    Michael



  • Eine Frage noch:

    kann man sich beim Debuggen irgendwie anzeigen lassen, wo der aktuelle "Lese-Zeiger" von BinaryReader gerade steht, also das wievielte Byte in der Datei als nächstes gelesen werden würde?

    Gruß
    Michael



  • Ja, mittels

    int pos = binaryReader.BaseStream.Position;
    

    (sofern der Stream das unterstützt 😉

    Edit: ups, sind ja hier im C++/CLI-Forum, also

    int pos = binaryReader->BaseStream->Position;
    


  • Hallo,

    Th69 schrieb:

    Edit: ups, sind ja hier im C++/CLI-Forum, also

    int pos = binaryReader->BaseStream->Position;
    

    Ah, das ist ja ganz einfach. Danke für den Hinweis !

    Gruß
    Michael


Anmelden zum Antworten