Boost::filesystem -> need help



  • Hallo allerseit,
    sitze derzeit über einer Plattformübergreifenden Filesearch Funktion.
    Läuft eigentlich auch ganz ok soweit, ich bekomme jedoch bei einer zu großen Anzahl an vorhandenen Unterordnern und Files eine Fehlermeldung. 😕

    Bei einer genaueren Zuweisung des Pfads macht das Programm keine Probleme!

    Hier mal der Code:

    #include<boost/filesystem/operations.hpp>
    #include<iostream>
    #include<string>
    namespace bfs=boost::filesystem;
    
    // Search for a file with the name 'filename' starting in directory 'dir_path', 
    // copy the path of the file in 'pfound' if found, and return true.
    // Else return false.
    bool find_file(const bfs::path & dir_path, const std::string & file_name, bfs::path & pfound)
    {
    	if( !exists(dir_path) || !is_directory(dir_path) )
    		return false;
    	bfs::directory_iterator iter(dir_path), end_iter;
    	for(; iter!= end_iter; ++iter)
    	{
    		if( bfs::is_directory(*iter) )
    		{
    			if( find_file(*iter, file_name, pfound) )
    				return true;
    		}
    		else if( iter->leaf() == file_name )
    		{
    			pfound = *iter;
    			std::cout<<pfound<<std::endl;
    			return true;
    		}
    	}
    	return false;
    }
    
    int main(){
    	bfs::path my_path("c:\\");
    	bfs::path temp_path("");
    	if(!find_file(my_path,"test.cpp", temp_path)) std::cout<<"Konnte nicht gefunden werden!"<<std::endl;
    	system("pause");
    }
    

    Vielen Dank für eure Hilfe
    geneticZ



  • Mensch, wenn du Hilfe willst musst du auch sagen, was der Fehler ist.
    Ich rate jetzt einfach mal, es gibt einen Stack-Overflow. Dann musst du die Funktion iterativ (also die Logik hinter if(is_directory) { find_file } verschleifen). Versuch's mal.



  • hallo filmor,
    sorry dass ich keine Fehlermeldung dazu geschrieben habe, aber ich bekomme da auch nur von Boost die Exception Meldung reingeballert und die ist leider nicht sehr aussage kräftig. (Zumindest für mich)

    Hier die Meldung:

    First-chance exception at 0x7680b09e in boost-nexttry.exe: Microsoft C++ exception:
    boost::filesystem::basic_filesystem_error<boost::filesystem::basic_path<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,
    boost::filesystem::path_traits> > at memory location 0x0029f354..
    

    Wie kann ich die Funktion iterativ umschreiben?
    Eigentlich is die Funktion ja direkt von der Boost Seite und warum weisen die einen dann nicht darauf hin dass es Probleme mit dem Stack geben könnte?

    Warum gibt es kein Problem mit den Winapi Funktionen bei der genau der selben Datenmenge zum Durchsuchen?

    Danke für die Hilfe
    geneticZ



  • Oh, nein, das ist kein Stack-Overflow. Wahrscheinlich beschwert sich Boost.Filesystem nur, dass er auf eine Datei oder ein Verzeichnis nicht zugreifen kann. Fang die Exception in der Funktion. Das rekursive sollte es schon tun, so tief sind Verzeichnishierarchien normalerweise nicht.



  • Vielleicht solltest du mal "what()" von der Exception ausdrucken...



  • wie kann ich das Abfangen, ich steh grad echt auf dem Schlauch!



  • geneticZ schrieb:

    wie kann ich das Abfangen, ich steh grad echt auf dem Schlauch!

    Du bekommst ja eine Exception geworfen. Und wenn du die fängst (catch ), dann kannst du dort auch what () aufrufen und du bekommst eine Beschreibung des Problems.



  • ja, aber was ich gerade gar nicht begreife is halt, dass ich in meinem Code die Exception gar nicht werfe 😞

    Normal wäre das ja try - catch...
    Aber wo muss ich hier mit dem catch ansetzen?

    Danke



  • geneticZ schrieb:

    ja, aber was ich gerade gar nicht begreife is halt, dass ich in meinem Code die Exception gar nicht werfe 😞

    Normal wäre das ja try - catch...
    Aber wo muss ich hier mit dem catch ansetzen?

    Danke

    Die musst auch nicht unbedingt DU werfen. Das ist ja der Sinn, dass die jemand anderst werfen kann und DU darauf reagieren kannst.
    Du solltest dich mal mit Exceptions beschäftigen. 🙄



  • drakon schrieb:

    Die musst auch nicht unbedingt DU werfen. Das ist ja der Sinn, dass die jemand anderst werfen kann und DU darauf reagieren kannst.
    Du solltest dich mal mit Exceptions beschäftigen. 🙄

    Da gebe ich dir absolut recht!
    Und zum guten Einstieg könntest du mir gerade mal bisl unter die Arme greifen und mir sagen wie und wo ich das hier ansetzen kann 😃





  • Ganz einfach, so geht das:

    int main() { 
        bfs::path my_path("c:\\"); 
        bfs::path temp_path(""); 
    
        try {
            if (!find_file(my_path,"test.cpp", temp_path))
                std::cout << "Konnte nicht gefunden werden!" << std::endl; 
        }
        catch (std::exception const& e) {
            std::cout << "EEEEERROR!!!!11elf" << std::endl;
            std::cout << "  type: " << typeid(e).name() << std::endl;
            std::cout << "  message: " << e.what() << std::endl;
        }
        system("pause"); 
    }
    

    Wenn man so nur exceptions fangen könnte die unmittelbar im try {} Block stehen wäre die ganze Sache ja auch ziemlich sinnlos, nicht? 😉

    D.h. catch fängt alle passenden Exceptions die im try {} Block irgendwo geworfen werden, ganz egal wie "tief" in irgendwelchen Unterfunktionen die geworfen werden. Ausser natürlich wenn sie "davor" schon gefangen werden, d.h. "näher" an der Stelle wo sie geworfen werden. ("näher" wäre hier z.B. ein catch Block in der Funktion find_file)

    Die Feinheiten kannst du ja nachlesen, ich schätze die Links von drakon werden das wohl genauer erklären.



  • super vielen Dank!

    EEEEERROR!!!!11elf
      type: class boost::filesystem::basic_filesystem_error<class boost::filesystem:
    :basic_path<class std::basic_string<char,struct std::char_traits<char>,class std
    ::allocator<char> >,struct boost::filesystem::path_traits> >
      message: boost::filesystem::basic_directory_iterator constructor: Zugriff verw
    eigert: "c:\$Recycle.Bin\S-1-5-21-1829455090-3793272444-3375908254-500"
    Drücken Sie eine beliebige Taste . . .
    

    Also, wie ihr vermutet habt wird der Zugriff verweigert.
    Wie kann ich dieses Problem lösen?



  • Naja, entweder fangen und ignorieren, oder gucken ob du es mit den "non throwing" Funktionen irgendwie gebacken bekommst.
    (Ich weiss nicht von welchen Funktionen es alles non-throwing Versionen gibt, daher weiss ich auch nicht ob man damit auskommt)

    Auf jeden Fall müsstest du die find_file Funktion umbauen.



  • so, also ich weiß momentan wirklich überhaupt nicht wie ich damit umgehen soll 😞

    Exception ignore is ja auch nicht wirklich das ware oder?
    Gibt es nicht ne möglichkeit Ordner ohne zugriff zu überspringen?

    Danke für die Hilfe
    geneticZ


Log in to reply