Probleme beim binären Lesenvon Dateien
-
Hallo,
Ich habe ein paar Probleme beim binären Lesen von Dateien und hoffe ihr könnt mir da etwas weiterhelfen.
Ich habe mir Folgendes überlegt:
Ich lese eine Datei vollständig und byteweise aus. Danach speichere ich die Datei in einem char-Array zwischen, da ein char genau ein Byte groß ist. das sieht bisher so aus:inline unsigned int readFile(char* pathToFile, char* byteArray){ char *fileBuffer; /* * open file */ FILE *fin = fopen(pathToFile, "r"); if (fin == NULL) return false; /* * get file size */ struct stat buf; stat(pathToFile, &buf); unsigned int fileSize = buf.st_size; //and allocate memory fileBuffer = new char[fileSize]; /* * readfile now */ fread(fileBuffer, sizeof(char), fileSize, fin); byteArray = fileBuffer; fclose(fin); return fileSize; }Ich denke, dass es bis hier keine Probleme gibt. Nun muss ich die Datei aber verarbeiten:
z.B. muss ich an einer gewissen stelle 4 Byte auslesen und diese Daten weiterverwenden. Ich kennzeichne mal diese Stelle:... E0 00 00 00 ...Da ich generell häufig 4 Byte Blöcke lese, dachte ich dass ich ein union verwende:
union 4byte { unsigned long data; char BYTE[4]; };und dieses union benutze ich dann in einer parse-funktion folgendermaßen:
for(unsigned int i = begin; i <= end; i++) { if(counter < 4) { union.BYTE[counter] = byteArray[i]; cout<<byteArray[i]<<endl; } counter++; }Das Problem ist nun folgendes:
Diese Stelle besitzt den Dateninhalt E0 was einem Dezimalwert von 224 entspricht. diesen Wert möchte ich nun gerne in meinen union speichern aber ich kriege Datenmüll raus. Schon das std::cout in der Parse-funktion liefert mir keine passenden ASCII Symbole sondern:^ _ ] �Ich persönlich würde gerne wissen, wie ich diese 4 Bytes speichern kann???
-
Ohje, ohje...

Dein Code ist fast komplett in C geschrieben, nur
newundcout/endlsind C++. In C++ verwendet man std::ifstream bzw std::ofstream für Dateien, std::string für Zeichenketten und std::vector für Arrays.Nun gut, warum dein Code nicht funktioniert, liegt an der Wert<->Referenz-Übergabe. Du übergibst einen Zeiger (byteArray) an die Funktion, diesem Zeiger weist du innerhalb der Funktion etwas zu. Dabei wird aber nur der übergebene Zeiger lokal verändert. Der Zeiger, den du beim Funktionsaufruf übergeben hast, bleibt unberührt.
Das Ganze mal in C++-ish:
#include <fstream> #include <exception> size_t getFileSize( const std::ifstream& file ) { size_t orig = file.tellg(); // Merken, wo der Dateizeiger gerade ist file.seekg( 0, std::ios::end ); // Dateizeiger an's Ende setzen size_t size = file.tellg(); // Aktuelle Position (also Dateigröße) holen file.seekg( orig, std::ios::beg ); // Wieder an die vorherige Position setzen return size; } std::vector<char> readFile( const std::string& file_path ) { using namespace std; // Datei öffnen, Exception werfen falls Datei nicht geöffnet werden konnte ifstream file( file_path.c_str(), ios::binary ); if ( ! file ) throw exception( std::string("File '" + file_path + "' not found!") ); // Buffer erstellen, im Konstruktor geben wir die Größe an std::vector<char> buf( getFileSize( file ) ); // Datei komplett einlesen file.read( &buf[0], buf.size() ); // Datei schließt sich automatisch // Den Dateiinhalt zurückgeben return buf; }Wenn du boost drauf hast oder es dir holst (gute und verbreitete C++-Bibliothek), dann bekommst du die Dateigröße auch bequemer:
... std::vector<char> buf( boost::file_size( path ) ); // Irgendwie so ...edit: Du kannst natürlich auch in einen
std::vector<int>oder Ähnliches einlesen, aber auch aus dem char-vector die ints/longs rausholen.
-
Ich wollte bewusst auf Listen verzichten. Ich versteh nur nicht, genau warum diese funktion nicht funktioniert, ich übergebe doch einen Zeiger. Dann allokiere ich Speicher mit new und schreibe danach rein. Theoretisch müsste nach der Übergabe des Zeigers (zb in der amin fkt.) was darin zu lesen sein.
inline unsigned int readFile(char* pathToFile, char *byteArray){ /* * open file */ FILE *fin = fopen(pathToFile, "r"); if (fin == NULL) return false; /* * get file size */ struct stat buf; stat(pathToFile, &buf); unsigned int fileSize = buf.st_size; //and allocate memory byteArray = new char[fileSize]; /* * readfile now */ fread(byteArray, sizeof(char), fileSize, fin); fclose(fin); return fileSize; }
-
Probier's mit ner Referenz auf den Zeiger. Ich würde dir aber dringend raten, richtig auf C++ umzusteigen. Mit deinem 3/4-C und 1/4-C++ wird das nichts, dann kannst du keins von beiden richtig.
Die Bücher "C++ Primer" und "Thinking in C++" Teil 1 und 2 sollen gut sein.
-
ah kanns mir denken:
es wird eine kopie von dem pointer erstellt und die kopie mit new abgehandelt...
ich habe ne referenz genommen.
an sich würde ich auch für das projekt leiber ne liste nehmen, aber leider kann ich das nicht benutzen ):