fStream EOF vor Dateiende
-
ich habe folgendes Problem: Ich habe eine Datei die mit (mir bekannten) Daten gefüllt ist
----------------
Nun lese ich die Daten aus, das funktioniert auch soweit ganz gut bis ich auf irgendein Sonderzeichen stoße - dann bricht das Lesen der Datei ab so als wäre das Zeichen eine Art EOF Zeichen.- FAString besteht immer aus 4Bytes Integer (Länge des Strings) und dem String
Hier das Format:
4 Byte ----- Länge von Chararray:
V Byte ----- Chararray1 Byte -----byte
4 Byte ------ integer
4 Byte ------ integer4 Byte ------ integer
4 Byte ------ integer4 Byte ------ integer
4 Byte ------ integer (größe der PNG Datei)
X Byte ------ PNG-Datei innerhalb dieser DateiCAIPReader::CAIPReader(std::string FileName) { this->CFileIO::CFileIO(FileName); std::string AIP_String = ReadFAString(); //OK byte Type = ReadByte(); //OK int Height = ReadInteger(); //OK int Width = ReadInteger(); //OK int SingleHeight = ReadInteger(); //OK int SingleWidth = ReadInteger(); //OK int FrameCount = ReadInteger(); //OK //Hier PNG Load //>>>>>>>>>>>>> int PNGSize = ReadInteger(); //OK byte *PNGFile; PNGFile = new byte[PNGSize]; ReadFile(PNGFile,PNGSize); //NICHT OK, anstatt 1454 Bytes liest er nur 5 //<<<<<<<<<<<<< } CFileIO::CFileIO(std::string &FileName) { Stream = new std::fstream(); Stream->open(FileName.c_str(),std::ios_base::in || std::ios_base::out || std::ios_base::binary); } byte CFileIO::ReadByte() { char memblock; Stream->read(&memblock,1); return (byte) memblock; } int CFileIO::ReadInteger() { char memblock[4]; Stream->read(memblock,4); int Output; CopyMemory(&Output, memblock,4); return Output; } std::string CFileIO::ReadFAString() { //length char memblock[4]; Stream->read(memblock,4); int Count; CopyMemory(&Count,memblock,4); //String char *Str; Str = new char[Count]; Stream->read(Str,Count); std::string Output = ""; for (int i = 0; i < Count ; i++) { Output = Output + Str[i]; } delete[] Str; return Output; } void CFileIO::ReadFile(void* Buffer, int Size) { int bla = Stream->readsome((char*) Buffer,Size); //Hier werden anstatt 1454 Bytes 5 Bytes gelesen if (bla < Size) Global->Error("Hier zuwenig gelesen"); }und hier die Datei die ich lesen will (HEX da ganz viele Sonderzeichen nicht als Text im Forum benutzt werden können)
00000000h: 04 00 00 00 54 65 73 74 01 80 00 00 00 80 00 00 00000010h: 00 40 00 00 00 40 00 00 00 04 00 00 00 AE 05 00 00000020h: DB C7 BD B9 6A 00 89 50 4E 47 0D 0A 1A 0A 00 00 00000030h: 00 0D 49 48 44 52 00 00 00 80 00 00 00 80 08 06 00000040h: 00 00 00 C3 3E 61 CB 00 00 05 75 49 44 41 54 78 ....das es ein Zeichen ist was das ganze auslößt ist nur eine starke Vermutung da wenn ich das Zeichen rauslösche er mehr bytes liest.
Danke im voraus
-
hola
nimm anstatt 'readsome' 'read'
readsome: Reads a block of data of up to n characters and stores it in the array pointed by s, but unlike member function read, readsome stops reading if the memory buffer associated with the stream runs out of characters, even if the End-Of-File has not yet been reached. The function is intended to be used to read binary data from certain types of asynchronic sources that may wait for more characters, since it stops reading when the local buffer exhausts, avoiding potential unexpected delays.Meep Meep
-
Wenn ich read benutze passiert etwas ähnliches,
anstatt der 5 Zeichen werden (vermutlich) 1454 Bytes "gelesen"
wobei die ersten 5 Bytes den Daten der Datei ab dem Punkt wo ich wirklich lesen wollte entsprechen, der Rest ist die ganze Zeit das gleiche Zeichen: "í"
-
Ich habe das selbe Problem (binärer inputstream auf eine Datei) und bin deshalb auch an einer Antwort interessiert. Ich verwende auch read() und nach einer gewissen Anzahl bekomme ich ein vorzeitiges eof(). Wenn ich vorher ein seek an eine andere Stelle nach der eof-Position mache, ändert das auch nichts. Ich bekomme nach kurzer Zeit wieder ein eof().
Weil ich an der Stelle nicht weiter komme, verwende ich statt einem stream nun die <stdio.h>. Die funktioniert problemlos mit der Datei.
-
Hallo,
Dragonling schrieb:
Ich habe das selbe Problem (binärer inputstream auf eine Datei) und bin deshalb auch an einer Antwort interessiert. Ich verwende auch read() und nach einer gewissen Anzahl bekomme ich ein vorzeitiges eof(). Wenn ich vorher ein seek an eine andere Stelle nach der eof-Position mache, ändert das auch nichts. Ich bekomme nach kurzer Zeit wieder ein eof().
Weil ich an der Stelle nicht weiter komme, verwende ich statt einem stream nun die <stdio.h>. Die funktioniert problemlos mit der Datei.
Ohne Code keine genaue Analyse möglich :). Und am besten so gekürzt, dass nur der Problem-Teil vorgestellt wird.
MfG,
Probe-Nutzer
-
OK, dann kommt hier ein Code-Ausschnitt:
#include <iostream> #include <fstream> ... unsigned long lEntrys, lDirStart, lFlag; char cBuf[4]; char cFilename[256]; unsigned int i=0, j; ifstream is; ... is.open(mFilename.c_str(), ios_base::in||ios_base::binary); is.read(cBuf, 4); is.read((char*)&lFlag, 4); is.read((char*)&lDirStart, 4); is.seekg(lDirStart); is.read((char*)&lEntrys, 4); while (!is.eof() && i < lEntrys) { i++; is.getline(cFilename,256,0x00); lEnt = new ERBEntry; lEnt->mFileName = cFilename; is.read((char*)&lEnt->mLength, 4); is.read((char*)&lEnt->mOffset, 8); is.read((char*)&lEnt->mTime, 8); // Eintrag zu Directory hinzufügen lDir->addEntry(lEnt); }lEntrys enthält den Wert 7326 (ist auch korrekt), i enthält am Ende der Schleife den Wert 5! Und wenn ich mir die Datei anschaue, dann hat er tatsächlich nach dem 5. Eintrag aufgehört, obwohl noch unzählige (7321 um genau zu sein) folgen.
-
Wie sieht es aus, wenn man es so:
#include <iostream> #include <fstream> ... unsigned long lEntrys, lDirStart, lFlag; char cBuf[4]; char cFilename[256]; unsigned int i=0, j; ifstream is; ... is.open(mFilename.c_str(), ios_base::in||ios_base::binary); is.read(cBuf, 4); is.read((char*)&lFlag, 4); is.read((char*)&lDirStart, 4); is.seekg(lDirStart); is.read((char*)&lEntrys, 4); while (i < lEntrys && is.getline(cFilename,256,0x00)) { i++; lEnt = new ERBEntry; lEnt->mFileName = cFilename; is.read((char*)&lEnt->mLength, 4); is.read((char*)&lEnt->mOffset, 8); is.read((char*)&lEnt->mTime, 8); // Eintrag zu Directory hinzufügen lDir->addEntry(lEnt); }schreibt?
MfG,
Probe-Nutzer
-
"Mit Gewalt" weiter zu lesen habe ich auch schon versucht.
In cFilename und in den anderen Variablen (BTW: ich habe sie nur für meinen Test in der class ERBEntry als "public" deklariert, also bitte keine Hinweise deswegen
) kommt dann nur Müll an.
Ich habe auch schon versucht, den read in ->mTime durch einen relativen seek von 8 Bytes zu überspringen, ändert aber auch nichts daran, dass das Einlesen abbricht.
Ich kann aber auch mal versuchen, nach dem addEntry ganz brutal ein is.clear() einzubauen, damit der stream im Fehlerfall wieder "freigeschaltet" wird.
-
Dragonling schrieb:
"Mit Gewalt" weiter zu lesen habe ich auch schon versucht.
Bezieht sich das auf meinen Code? In meinem Code ist nichts "gewalttätiges"

getline gibt den Zustand des ifstream zurück, und wenn es irgendein Problem gibt (das muss nicht nur EOF sein), dann wird nicht weiter gelesen.
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
Dragonling schrieb:
"Mit Gewalt" weiter zu lesen habe ich auch schon versucht.
Bezieht sich das auf meinen Code? In meinem Code ist nichts "gewalttätiges"

Nein :), ich meine, ich habe mit "while (i < lEntrys)" weiter gelesen, mit dem Ergebnis, das der stream nur Müll geliefert hat.
-
Ja, dann schreib' doch mal, was mit meinem Code passiert. Welchen Wert hat i nach Verlassen der Schleife? Welche state-flags (rdstate() ) sind gesetzt nach der Schleife?
MfG,
Probe-Nutzer
-
Ich schreibe es, sobald ich zu Hause bin und es testen kann. Das wird so gegen 17-18 Uhr sein, wenn nichts dazwischen kommt

-
Dein Code ändert nichts, die Schleife wird bei Index 5 verlassen. Das Ergebnis von rdstate() ist 3.
Und ein is.clear() am Ende der Schleife hat auch nichts geändert.[Update]
Der stream-Status wechselt beim 5. Eintrag nach der Zeile "is.read((char*)&lEnt->mLength, 4);" auf "3"?!?[Update 2]
Wenn ich alle reads, außer dem getline, durch "is.seekg( x, ios_base::cur ); " ersetze, wird die Datei bis zum Ende gelesen.
-
Ich habe die Lösung gefunden:
Ich darf den Stream nicht mit
is.open(mFilename.c_str(), ios_base::in || ios_base::binary);
öffnen, sondern nur mit
is.open(mFilename.c_str(), ios_base::binary);
Wenn ich das "ios_base::in||" weg lassen, wird die Datei bis zum Ende gelesen.
-
Dragonling schrieb:
Ich habe die Lösung gefunden:
Ich darf den Stream nicht mit
is.open(mFilename.c_str(), ios_base::in || ios_base::binary);
öffnen, sondern nur mit
is.open(mFilename.c_str(), ios_base::binary);
Wenn ich das "ios_base::in||" weg lassen, wird die Datei bis zum Ende gelesen.Ich habe es jetzt genauso gemacht wie du, anstatt fstream nen ifstream genommen und Zugriffsmodus nur ios_base::binary
trotzdem liest er bei mir nicht bis zum Ende.
Wenn ich aber das Zeichen wo er aufhört ersetze bzw. einfach Alpha-Numerische Zeichen da einfüge dann liest er zumindest nen Stück weiter bis er wieder an irgendeiner Stelle meint die Datei wäre zu Ende *verzweifel*