fStream EOF vor Dateiende



  • 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*


Anmelden zum Antworten