KINGx - Das inoffizielle PlayStation Forum & News Portal

Normale Version: Lesen eines Filestreams mit C
Sie sehen gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Huhu Leute,
für mein aktuelles Projekt, programmiere ich gerade einen Unpacker für ein bestimmtes Archivformat.
Nun habe ich aber ein Problem beim Einlesen mit der Funktion fread Big Grin
Im Hexeditor steht nun diese Reihenfolge:

Code:
00 00 14 DD

Aber im Programm bekomme ich immer:

Code:
DD 14 00 00

Ich brauche aber die richtige Reihenfolge :-/
Was soll ich tun?

Du musst das word shiften..

oder du gibst das word einfach richtig ein Big Grin
Das Shiften ist eine Möglichkeit aber mit größer werdenden Datentypen, oder gar großen Datein gibt es Probleme.

Was meinst du mit richtig eingeben?
Ich habe extra einen Integer ( 4 Bytes ) benutzt, da in diesem Format nun mal so hohe Werte möglich sind.

Chaosduckman :
Das Shiften ist eine Möglichkeit aber mit größer werdenden Datentypen, oder gar großen Datein gibt es Probleme.

Was meinst du mit richtig eingeben?
Ich habe extra einen Integer ( 4 Bytes ) benutzt, da in diesem Format nun mal so hohe Werte möglich sind.


Vergiss das 2te was ich gesagt hab.. hab dich falsch verstanden..

Wieso würde es probleme geben? Du shiftest einfach word für word.. mehr ist eig. auch garnicht dran.. dann solltest du es haben..

bin atm auch zufaul das ich dir einen shiftcode schreiben könnte.. ;D

Hi,

ich denke das hängt von dem FileSystem ab auf dem die Daten liegen...Da gibt es LittleEndian und BigEndian...davon hängt ab in welcher Reihenfolge das Hi- und das Low-Word eines Wertes geschrieben/gelesen werden. Beim lesen der Daten vom filesystem (z.Bsp.) ein Integer wird dieses immer korrekt eingelesen...beim anschauen des Files mit einem HEX-Editor kann dies aber bedeuten dass die Informationen scheinbar "vertauscht" dargestellt wird...

Du musst deinen eignene Code eigentlich nur anpassen wenn du die Datei zwischen 2 Betriebssystemen wie Window's, UNIX etc. austauschst...auch Win NT macht es glaube ich wieder etwas anders...

Einen Konvertierungscode von BigEndian nach LittleEndian kannst du in meinem OpenSource-Projekt für den Monzoom-Converter finden (http://code.google.com/p/pspmz2gu) [File: MonzoomAPI.cpp Methoden: ClMonzoomFile::convertLE_BE]

PS: wenn du den Integer mit deinem eigenen Programm in ein File schreibst und wieder einliest (auf dem selben Betriebssystem) ist dies immer richtig egal wie es in einem Hex-Editor aussieht Wink
Exakt, Anmabagima. Der Grund, warum bei dir der Text sich von der Ausgabe unterscheidet liegt am Little Endian / Big Endian System.

Dies ist unter anderem auch bei der PSP Programmierung entscheidend, da der PSP Prozessor Little Endian als data encoding aufweist. Somit ist z.B. ein ELF file oder ein RAM dump an vielen einzelnen Stellen "gespiegelt". Diese Bereiche werden durch die jeweiligen Daten Typen spezifiziert.

Ein einzelnes Byte ist, egal ob Little Endian oder Big Endian, immer an der selben Position.

ELF File: 0x7F'E'L'F' (Dies ist die magic number, die files als ELF Datei identifiziert und besteht aus vier einzelnen Bytes. Diese Bytes werden als EI_MAG0 - EI_MAG3 bezeichnet). Egal ob das file im Littel Endian oder Big Endian Format vorliegt, die Positionen der Bytes untereinander sind immer gleich.

Bei größeren Datentypen ist dies anders, nehmen wir ein "Word" (32 Bit) als Datentyp und ein Little Endian File als Grundlage:

Wir nehmen mal 0x3C0A0890 als unseren 32 Bit Wert. Jetzt musst du wissen, dass Speicher im Prinzip nur ein einziges großes Array ist (grob gesagt). Jede Adresse im Speicher stell einen Array Index dar, die Adresse 0 entspricht dem Index [0], Adresse 1 == Index[1], usw. Jede Adresse lädt ein Element des Arrays, Array Elemente sind einzelne Bytes. Um also ein 32 Bit Wert (4 byte) in unser großes Speicherarray zu laden, müssen wir es zuerst in 4 Bytes aufsplitten, da ja jede Speicheradresse nur ein Byte speichern kann.

3C 0A 08 90 (so gesehen blicken wir aber immer noch auf einen ursprünglichen 32 Bit Wert). Unser 32 Bit Wert, bzw. die einzelnen 4 Bytes werden jetzt an 4 aufeinander folgende Speicheradressen geschrieben, z.B. ausgehend von der Adresse 0x1000 bis 0x1003 (somit haben wir vier Adressen an denen wir unsere Bytes speichern können).

Big Endian sagt nun aus, dass das "most-significant" Byte (das am "meisten" gewichtete Byte) an die kleinste aktuelle Adresse gespeichert wird (die Adresse 0x1000 in unserem Fall, da ja die Speicheradressierung aufsteigend ist, d.h. die nachfolgende Adresse ist größer als die vorherige).

Was ist das "most-significant" Byte in unserem 32 Bit Datentyp (0x3C0A0890)?
Nun, unser 32 Bit Datentyp besteht ja aus 4 Byte. Nun besagt eine Konvention, dass die Gewichtung eines Byte (gilt auch für Bit) von Rechts nach links aufsteigend ist. Also nimmt die Bedeutung vom ganz rechtem Byte bis zum ganz linkem Byte immer mehr zu. In unserem Beispiel bedeutet dies, dass das Byte 0x90 die kleinste Bedeutung hat und das Byte 0x3C die höchste Bedeutung hat.

Somit wird unser Wort wie folgt in das Speicherarray geschrieben:

Adresse Wert
0x1000 0x3C
0x1001 0x0A
0x1002 0x08
0x1003 0x90

Little Endian:

Zwischen Little Endian und Big Endian besteht ein bedeutender Unterschied:
Beim Little Endian wird das least-significant Byte (wieder: gilt auch für Bits) in die kleinste aktuelle Adresse geschrieben. Da wir jetzt wissen, dass das ganz rechte Byte eines Datentyps immer das least-significant Byte ist, kennen wir jetzt auch die Little Endian Repräsentation.

Nochmals hier unsere 4 Bytes unseres 32-Bit Datentyps: 3C 0A 08 90

Adresse Wert
0x1000 0x90
0x1001 0x08
0x1002 0x0A
0x1003 0x3C
Referenz-URLs