Geschwindigkeitsproblem beim Finden einer Zeichenfolge mit fstream



  • Hallo alle zusammen,

    Meine frage: gibt es eine möglichkeit, die position einer bestimmten Zeichenfolge in einem fstream so zu ermitteln(möglichst schnell!) dass ich sie mit seekg() anspringen kann?
    Oder gibt es andere methoden um ein bestimmte Zeichenfolge in einer Datei schnell zu finden und den Auslesezeiger auf die entsprechende Postion zu bekommen?

    Ich bin mit dem Durchsuchen einer Standarttextdatei nach einer bestimmten Zeichenfolge beschäftigt.

    ich gehe ungefähr so vor :
    while (not_found){
    getline(Datei.txt,buffer)
    prüfe ob der zeichenfolge entspricht
    Wenn ja --> zeile gefunden
    }

    Die Dateien auf die das Programm stoßen könnte können aber durchaus 40 bis 200 MB groß werden. Da ist diese Methode viel zu lahm.

    Ich habe bereits 2 Stunden bei Google und in der Forumssuchfunktion zugebracht aber immer nur die Lösung mit dem zeilenweisen Durchsuchen gefunden. Ich könnte natürlich auch zu beginn des programms eine Tabelle mit den Positionen der Zielenanfänge anlegen aber dann müsste der User zu beginn ewig warten.

    Ich hoffe Ihr könnt mir Helfen.

    S.



  • Unter Umständen (bin mir eigentlich ziemlich sicher 😉 ) wirds schon viel schneller wenn Du die komplette Datei erstmal in den Speicher lädst und dann nach den entsprechenden Zeichen suchst.



  • Schau mal hier rein. Vielleicht ist das die Lösung für Dein Problem.



  • Wow, das ging ja mal fix.

    Danke an Alle .

    Ich hab im Link von Jencs eine Mathode gefunden die das ganze ca 50% schneller erledigt. Herzlichen Dank nochmal. Ich werde versuchen das ganze mit ein paar lexikografischen Tricks zu kombinieren um noch ein bischen geschw. raus zu holen.

    Danke
    S.



  • Nachtrag:

    Weiß jemand von Euch wie ich bei einem CArchive an den AuslesePointer des dazugehörigen CFile`s komme?

    mit archiv.GetFile().GetPosition() bekomme ich die Fehlermeldung:
    Der linke Teil von "GetPosition()" muss eine Klasse/Struktur/union sein

    Danke
    S.



  • CFile* GetFile( ) const;

    Das ist ein Zeiger, da wirst du mit . nix. 😉



  • Ah ok.
    Danke, das war das Problem.
    Jetzt klappt es. Allerdings bekomme ich immer den gleichen File Pointer zurück egal wie lange ich die Datei durchlaufe

    ich gehe folgendermaßen vor:

    Deklaration:

    CFile composed_Source(composedFileStr, CFile::modeRead);
    CArchive source_archive(&composed_Source, CArchive::load, composed_Source.GetLength());
    CString line;
    

    Dann wir die Datei durchlaufen bis die gesuchte Zeile gefunden ist und der Pointer wird gespeichert(Das if(FOUND) ist natürlich Pseudocode):

    while(source_archive.ReadString(line)){
    if (FOUND){
    //lookUpVector[yPos][xPos]=source_archive.GetFile()->GetPosition();
    lookUpVector[yPos][xPos]=composed_Source.GetPosition();
    }
    

    Aber: beide Varianten(sowohl direktzugriff auf Cfile.GetPosition() als auch GetFile()->GetPosition) liefern immer einen Pointer auf den Anfang der Datei.

    Woran liegt das?
    Muss ich den Auslesepointer immer von Hand mitverschieben?

    S.



  • Die Fileoperationen sind ja schon durch das load in CArchive abgehandelt, da 'bewegt' sich kein CFile Zeiger mehr. Da musst Du schon selbst mitrechnen, was ja auch kein Hexenwerk ist.



  • Bachtler schrieb:

    Ich könnte natürlich auch zu beginn des programms eine Tabelle mit den Positionen der Zielenanfänge anlegen aber dann müsste der User zu beginn ewig warten.

    die positionen der zeilenanfänge bringen wenig.
    die positionen der wörter selbst wären fein für schnelles suchen.
    wird der benutzer nach vielen wörtern suchen? bei vielen wörtern wäre es vielleicht schon schneller, vorher nen index zu bauen.
    oder darfste nen index neben die datei auf die platte legen und ihn dann nur aktualisieren, wenn der benutzer in dieser datei was sucht und die datei seit der indexerstellung geändert wurde?



  • @jencas :

    Ok dann zähl ich halt selbst immer ein Byte weiter.

    @volkard:
    Tut mir leid ich habe mich etwas ungenau ausgedrückt : es wird quasi nach trennzeichen gesucht die die Grenze eines bestimmten Datensatzes markieren und dieser wird dann gelesen.
    Es wird auch nach jedem Trennzeichen nur einmal gesucht. dafür stehen aber auch mehrere Tausend zur verfügung.
    Das mit der Index Datei ist gar keine schlechte Idee zumal sich der Inhalt der Auszulesenden Datei niemehr ändern sollte .

    Danke Euch allen
    S.


Anmelden zum Antworten