std::ifstream fehlerbehandlung
-
hi,
wie kann ich herausfinden, ob ein std::ifstream("myfile.txt") fehlschlägt, weil die Berechtigung zum lesen nicht vorhanden ist, oder weil die Datei nicht vorhanden ist?
-
std::ifstream ifs("myfile.txt") if ( !ifs ) std::cerr << "Fail!" << std::endl;
-
Ich habe mich unklar ausgedrückt, ich möchte wissen welcher der beiden Fälle aufgetreten ist, nicht, ob einer der beiden aufgetreten ist.
-
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?
-
@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 vonsystem_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.
-
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ällenno_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 vonsystem_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
(desstd::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 Werfenios_base::failure
bringt auch keine Information, denn die steht imopen
desfilebuf
.
Der einzige der werfen könnte, weil er die Information besitzt warum es schief gegangen ist, ist derbasic_filebuf
. Lt. Standard tut er aber genau das nicht. Ergo bleibt nur der Weg übererrno
.
Und ja -errno
kann thread specific sein.Gruß
Werner