Binäre Daten auslesen

kuhlmaehn

Erfahrenes Mitglied
Hi, ich scheitere gerade etwas an meinem Unvermögen ;) ..

Ich hab eine Datei in der Koordinaten gespeichert sind. Bis jetzt habe ich rausgekriegt, dass 16 bytes bzw 2 doubles einmal die X und die Y Koordinate behinalten.
Das sieht dann zB so aus:
Code:
3F A7 AF 72 2A 3A 3D DF A2 E5 92 D2 AF 72 2A D2
Also die ersten 8 Zeichen sind X und die zweiten Y.

Was ich jetzt nicht verstehe ist wie ich das als Zahlen darstellen soll.
Was bedeutet es überhaupt das es binär dargestellt wird?
Soll ich das jetzt einfach von Hexadezimal ins 10ersystem rechnen!?
Und wie mache ich sowas überhaupt in C#

Danke schonmal :\
 
es gibt die möglichkeit eine Datei Binär auszulesen mit System.IO.File.ReadAllBytes(); Damit erhälst du ein Bytearray. Wenn du das nun in ushort umwandeln willst musst du folgendes tun:
Code:
byte[] coords = File.ReadAllBytes(Dateipfad);
ushort[] coordsU = new ushort[coords.length/2];
for(int i = 0; i < coordsU.length; i++)
{
    coordsU[i] = (ushort)((coords[i*2] << 8) | coords[i*2+1]);
}

Dann hast du ein Array das die Koordinaten enthält.
 
Mh danke erstmal.

Wie genau ist denn dann die Ausgabe?
Bei 8 Byte bekomme ich 4 Felder im Array:
Code:
27242
11440
57083
2112
Warum 4 und nicht nur eins? :\
(Bei den 16 Byte halt 8)
Und könntest du den Code noch komentieren ich versteh leider gar nichts :-(
Das wäre nett :)

Danke!

[Edit]
Also eigentlich versteh ich nur 2 Zeilen nicht:
Code:
ushort[coords.Length / 2];
und
Code:
coordsU[i] = (ushort)((coords[i * 2] << 8) | coords[i * 2 + 1]);

Achso und wie würde das ganze dann andersherrum gehen?
 
Zuletzt bearbeitet:
also ich hoffe einfach mal ich hab das richtig verstanden was du wolltest: Die Datei auslesen, und dann jeweils zwei Bytes lesen, und zusammensetzen, also aus z.B.

00001101 und 01001101 (binär) 0000110101001101 erzeugen. Die ersten beiden wären byte Datentypen und der letzte ein short (byte = 8 Bits, short = 16 Bits). ushort ist aber ratsamer, da du ja keine Vorzeichen brauchst. Dafür ist
Code:
coordsU[i] = (ushort)((coords[i * 2] << 8) | coords[i * 2 + 1]);
da. coordsU[i] ist der aktuelle ushort - wert. Dann folgt eine Typumwandler, der das nachfolgende in ushort Konvertiert. Der weitere Code ist wirklich ein bisschen schwierig, wenn man sich damit nicht auskennt. coords[i * 2] ist das erste byte das gelesen wird (das wäre beim ersten schleifendurchlauf coords[0], beim zweiten coords[2] usw.) der << Operator verschiebt die bytes von coords[i * 2] nach links, und zwar um 8 (deswegen steht da eine 8 rechts vom Operator). Nach dem obigen Beispiel währe das erste Byte dann 0000110100000000. Wenn du nachzählst: 16 Bytes: ushort. Jetzt sollen aber die letzten acht nullen durch das zweite Byte ersetzt werden. Dafür ist das | da. | bekommt zwei Datentypen übergeben. Dann geht es alle bits durch, und erstellt in dem Datentyp der ausgegeben wird jeweils eine 1 an einer stelle an der eine oder zwei einsen in den beiden übergebenen Datentypen vorhanden ist. Dadurch entsteht dann 0000110101001101.

ushort[coords.length / 2] bringt so garnichts. Wenn man ein new davorschreibt (wie in meinem Code), dann erstellt das ein ushort Array das so lang ist, wie die hälfte der länge von coords.
 
Mh ich glaub das wollt ich nicht ^^
Ich weiss es aber auch nicht genau mit verwirrt gerade das binär..

Ich fang nochmal an..
Also ich hab ein Programm, welches Dateien speichert. Im Programm hatte ich ein simples Dreieck aus Strichen, bzw. Vertexen mit 3 Eckpunkten. Nun habe ich einmal gespeichert, dann einen der Eckpunkte versetzt und nochmal gespeichert. Das Resultat sieht man im Anhang. Nur diese 16 Bytes haben sich verändert. Mir wurde dann gesagt, dass die ersten 8 Bytes die X-Koordinate bilden, welche in einem Double gespeichert sind.
Wie kann ich diese X-Koordinate nun auslesen?
Vielleicht hattest du mich doch richtig verstanden, ich verstehe nur nicht warum es in 4 Teile geteilt wird :)
 

Anhänge

  • mh.jpg
    mh.jpg
    60,3 KB · Aufrufe: 40
ahh, ich glaube ich habs kapiert. Du willst also die ersten 8 Bytes auslesen und aneinanderhängen (wie bei mir im vorherigen Post beschrieben, nur halt mit 8 statt 2 Bytes). Und jetzt verstehe ich auch warum du die Zahlen Hexadezimal gepostet hast.

OK, dann geht das ganze so:
Code:
byte[] coords = File.ReadAllBytes(Dateipfad); // Coords enthält die 16 Bits
ulong[] XY = new ulong[2]; // Darin sollen am ende die beiden Koordinaten stehen
for(int i = 0; i < coords.length; i++) // Läuft für jedes coords Element 1 - mal durch
    XY[i / 8] |= (ulong)(coords[i] << (i / 8 == 0 ? (7 - i) * 8 : (15 - i) * 8 ));
Die letzte Zeile ist wieder etwas komplizierter. XY[i / 8] ist für die ersten 8 durchläufe XY[0], für die nächsten 8 XY[1]. |= ist wieder der | operator, nur diesmal mit dem =. Das funktioniert wie bei +=. XY[i] |= ... wird übersetzt in XY[i] = XY[i] | .... Dann kommt wieder der Konvertiert (ulong). Der Rest ist wirklich etwas schwierig: coords[i] ist das Aktuelle byte. Dann kommt die Abfrage i / 8 == 0. Das ist genauso wie bei dem XY[i - 8]. Für die ersten 8 ergibt die Abfrage true, für die anderen false. (7 - i) * 8 ist beim ersten durchlauf 56 ((7 - 0) * 8), beim zweiten 48 usw. Das ist die linksverschiebung. Das erste coords wird um 56 linksverschoben, das nächste um 48. (15 - i) * 8 ist nur deswegen dabei, dass man nicht bei der zweiten Koordinate eine - linksverschiebung erhält, ich glaube das ist nicht zulässig aber noch nie ausprobiert). Beim 9. Durchlauf (das erste Bit der Y Koordinate) währe das Ergebniss dann ja -8 (bei (7 - i) * 8: (7 - 8) * 8), also wird (15 - i) * 8 genommen, was beim 9. Durchlauf 56 ist (ja, und beim zweiten 48). Damit beginnt das ganze wieder von vorne.

Wenn du den code aber für mehr verwenden willst ist das etwas schwierig, da beim 17. Element der Fehler mit der Negativen Linksverschiebung auftritt (und wenn es keine Exception gibt, ein Fehler ist es trotzdem). Wenn du willst kann ich den Code noch für mehr Koordinaten aufmöbeln, aber heute nicht mehr. Ich würde dir aber noch empfehlen ein
Code:
if(coords.length == 16)
um die Schleife zu setzen, damit alle bugs ausgeschlossen sind.
 
Hallo,

die Umwandlung der Bytes in Double ist bei C# recht simpel. Nachdem du die Datei in ein Byte-Array eingelesen hast, kannst du mit der Klasse "BitConverter" die die Konvertierung erledigen.
Ich habe im Beispiel mal die Werte von deiner angehängten Grafik fest in ein Byte-Array hineingeschrieben:
C++:
byte [] buffer  = { 0x6A, 0x6A, 0x2C, 0xB0, 0xDE, 0xFB, 0x08, 0x40,
                    0xE6, 0xC6, 0xCE, 0xEA, 0xE4, 0x4F, 0xF4, 0xBF };


double X = BitConverter.ToDouble(buffer, 0); //  3.1229833377413359
double Y = BitConverter.ToDouble(buffer, 8); // -1.2695054218460711
Gruß
MCoder
 
Dank euch erstmal! :)

Bei dir Darkas kommt beim ersten mal für X 18446744073692458224 und für Y 18446744073286975231 raus. Warum kommt bei euch was unterschiedliches raus? :confused:
Kann ich denn bei dem Bitconverter dieses "Bytefeld" auch im Programm anhand der Datei erstellen?
 
Hallo,
diese Methode liest dir die komplette Datei ein und speichert sie in einem byte-Feld:
C++:
public byte[] ReadBinaryFile(string strPath)
{
    using( FileStream fs = File.Open(strPath, FileMode.Open, FileAccess.Read ) )        
    {
        byte[] buffer = new byte[4096];
        
        using( MemoryStream ms = new MemoryStream() )
        {
            while( true )
            {
                int nRead = fs.Read(buffer, 0, buffer.Length);

                if( nRead <= 0 )
                {
                    return ms.ToArray();
                }                           
                
                ms.Write(buffer, 0, nRead);
            }                        
        }
    }                                
}
Gruß
MCoder
 

Neue Beiträge

Zurück