std::ifstream fehlerbehandlung


  • Mod

    Was ist eine "Berechtigung"?



  • http://en.cppreference.com/w/cpp/io/basic_filebuf/open

    sieht für mich so aus als kann man mit der standardbibliothek nur unterscheiden, ob man die datei überhaupt öffnen kann oder nicht, mehr nicht.



  • Arcoth schrieb:

    Was ist eine "Berechtigung"?

    Ob ein Benutzer die Datei lesen/schreiben/ausführen darf .. in dem Fall geht es erstmal ums lesen.

    Finde ich halt blöd, möchte je nachdem dem Anwender sagen was los ist ... ob er die Berechtigungen prüfen muss, oder ob die Datei einfach nicht existiert.



  • Der C++-Standard garantiert Dir ausschließlich die Information, ob der fstream.open gut gegangen ist oder nicht.

    Falls ein Fehler aufgetreten ist, kann man je nach verwendeter Umgebung die Variable ' errno ' abfragen, die einen (Posix)Fehlercode liefert.

    if( errno == ENOENT ) // s. #include <cerrno>
        { // file not exists
    

    Die boost Library System bietet mit boost::system::error_code elegante Möglichkeiten an einen Fehlertext zu kommen.

    garantiert ist vom Standard aus gar nichts - kommt halt auf das System an, auf dem das läuft.



  • Danke, das ist auf jeden Fall eine Option.
    Allerdings habe ich in meiner Applikation mehrere Threads (die auch jeweils versuchen Dateien zu öffnen) ... wenn ich das mit errno gegenprüfe habe ich dann nicht eine art eine race condition?


  • Mod

    @Werner: Würde man das nicht so machen

    std::ifstream stream;
    	stream.exceptions( std::ios::failbit );
    	try
    	{
    	    stream.open("Blubfoo");
    	}
    	catch( std::ios_base::failure const& w )
    	{
    		if( w.code() == std::errc::no_such_file_or_directory )
    			std::cerr << "No such file";
    	}
    

    (Ungetestet, da bei mir ios_base::failure nicht von system_error ableitet.. merkwürdig)
    ~Edit: Gekürzt~



  • Arcoth schrieb:

    std::errc::no_such_file_or_directory
    

    Ist implementation defined ob das funktioniert oder nicht.

    asgfg schrieb:

    wenn ich das mit errno gegenprüfe habe ich dann nicht eine art eine race condition?

    Ne, errno ist thread_local.

    A separate errno value shall be provided for each thread.


  • Mod

    ENOENT schrieb:

    Arcoth schrieb:

    std::errc::no_such_file_or_directory
    

    Ist implementation defined ob das funktioniert oder nicht.

    Es ist auch implementation-defined, ob char 8 Bits hat. Leider kann ich keine Aussage treffen, in wievielen Fällen no_such_file_or_directory funktioniert... 😡



  • Arcoth schrieb:

    Es ist auch implementation-defined, ob char 8 Bits hat.

    Ein char hat immer Platz für 8 Bits. (8 Bits haben ⊂ 12 Bits haben.)



  • Arcoth schrieb:

    @Werner: Würde man das nicht so machen

    std::ifstream stream;
    	stream.exceptions( std::ios::failbit );
    	try
    	{
    	    stream.open("Blubfoo");
    	}
    	catch( std::ios_base::failure const& w )
    	{
    		if( w.code() == std::errc::no_such_file_or_directory )
    			std::cerr << "No such file";
    	}
    

    (Ungetestet, da bei mir ios_base::failure nicht von system_error ableitet.. merkwürdig)
    ~Edit: Gekürzt~

    Das war mein erster Gedanke als ich den Beitrag um 14:06 schrieb. Wobei std::errc hatte ich noch gar nicht auf dem Schirm - wieder was gelernt 🕶 .

    Da steht sich der Standard beim Öffnen einer Datei ein wenig selbst im Wege - beim open (des std::istream ) heißt es nämlich:

    void open(const char* s, ios_base::openmode mode = ios_base::in);
    Calls rdbuf()->open(s, mode | ios_base::in). If that function does not return a null pointer calls clear(), otherwise calls setstate(failbit) (which may throw ios_base::failure)

    D.h. die Fehlerbehandlung geht nur über den Pointer des filebuf . Und das Werfen ios_base::failure bringt auch keine Information, denn die steht im open des filebuf .
    Der einzige der werfen könnte, weil er die Information besitzt warum es schief gegangen ist, ist der basic_filebuf . Lt. Standard tut er aber genau das nicht. Ergo bleibt nur der Weg über errno .
    Und ja - errno kann thread specific sein.

    Gruß
    Werner


Anmelden zum Antworten