Der schnellste Weg, um zu überprüfen, ob eine Datei mit Standard-C++/C++11,14,17/C vorhanden ist?
Lesezeit: 6 Minuten
Vinzenz
Ich würde gerne den schnellsten Weg finden, um zu überprüfen, ob eine Datei in Standard-C++ 11, 14, 17 oder C existiert. Ich habe Tausende von Dateien und bevor ich etwas mit ihnen mache, muss ich überprüfen, ob sie alle existieren. Was kann ich stattdessen schreiben /* SOMETHING */ in der folgenden Funktion?
boost::filesystem scheint zu gebrauchen stat(). (Ausgehend von der Dokumentation.) Ich glaube nicht, dass Sie für FS-Aufrufe viel schneller arbeiten können. Der Weg, um das, was Sie tun, schnell zu machen, besteht darin, „das Betrachten von Tausenden von Dateien zu vermeiden“.
– Millielch
8. Oktober 2012 um 1:15 Uhr
TOCTOU Frage: Woher wissen Sie, dass die Datei zwischen Ihrer Prüfung vonexists() und Ihrer „etwas dagegen tun“?
– Pilkrähe
8. Oktober 2012 um 1:16 Uhr
@pilcrow Guter Punkt, aber es gibt eine ziemlich breite Palette von Anwendungen, die nicht so viel Korrektheit erfordern. Z.B git push macht sich wahrscheinlich nicht die Mühe, sicherzustellen, dass Sie den Arbeitsbaum nach der anfänglichen schmutzigen Prüfung nicht berühren.
– Millielch
8. Oktober 2012 um 1:27 Uhr
„Mir fällt keine C/C++-Implementierung ein, die das nicht hätte“ – Windows bietet keine POSIX-Umgebung.
– Jim Balter
8. Oktober 2012 um 1:58 Uhr
Mögliches Duplikat von std::ofstream, prüfen Sie vor dem Schreiben, ob die Datei existiert
– MDXF
27. Februar 2017 um 4:17 Uhr
PherricOxide
Nun, ich habe ein Testprogramm zusammengestellt, das jede dieser Methoden 100.000 Mal ausgeführt hat, halb für Dateien, die existierten, und halb für Dateien, die nicht existierten.
Ergebnisse für die Gesamtzeit zum Durchführen der 100.000 Aufrufe, gemittelt über 5 Läufe,
Methode
Zeit
exists_test0 (wenn stream)
0,485 s
exists_test1 (DATEI föffnen)
0,302 s
exists_test2 (Posix-Zugriff())
0,202 s
exists_test3 (Posix-Statistik())
0,134 s
Die stat() Funktion lieferte die beste Leistung auf meinem System (Linux, kompiliert mit g++), mit einem Standard fopen call ist die beste Wahl, wenn Sie sich aus irgendeinem Grund weigern, POSIX-Funktionen zu verwenden.
Keine der oben genannten Methoden prüft die Existenz, sondern die Zugänglichkeit. Ich kenne jedoch keine einzige Standard-C- oder C++-Methode, um die Existenz zu überprüfen.
– Inspektionsfähig
9. September 2013 um 21:32 Uhr
stat() scheint auf Existenz zu prüfen.
– el.pescado – нет войне
7. November 2013 um 16:57 Uhr
Jeder, der dies verwendet, muss daran denken, einzubeziehen, da sonst versucht wird, die falsche Statistik zu verwenden.
– Katianie
4. Februar 2014 um 14:41 Uhr
Ich stelle mir vor, für die ifstream-Methode brauchen Sie das nicht f.close() da f am Ende der Funktion den Gültigkeitsbereich verlässt. Damit return f.good() könnte die ersetzen if Block?
In MS Visual Studio 2013 ist diese Funktion verfügbar unter std::tr2::sys::exists("helloworld.txt");
– Konstantin
30. März 2015 um 4:41 Uhr
Ich hoffe wirklich, dass es nicht so sein wird std::existsdas wäre ziemlich verwirrend (denken Sie: existiert in einem STL-Container wie ein Set).
– einpoklum
17. Februar 2016 um 15:00 Uhr
Auch in Visual Studio 2015: #include <experimental/filesystem> bool file_exists(std::string fn) { std::experimental::filesystem::exists("helloworld.txt"); }
– Orwellophil
16. Februar 2017 um 12:49 Uhr
Vergiss es nicht #include <experimental/filesystem>
– Mohammed Nureldin
14. Juni 2019 um 13:55 Uhr
Dies funktioniert bei mir unter Windows (c++17), aber nicht unter Linux (GCC C++17). Irgendeine Idee warum?
– willem
11. Dezember 2019 um 14:35 Uhr
Ich verwende dieses Stück Code, es funktioniert bisher bei mir. Dies verwendet nicht viele ausgefallene Funktionen von C++:
Es kann jedoch fehlschlagen, wenn die Datei von einem anderen Programm gesperrt wurde oder wenn kein Zugriff auf die Datei besteht.
– Strahl
8. Juni 2015 um 18:48 Uhr
Müssen Sie den Stream schließen?
– Mo0gles
24. Juni 2015 um 6:55 Uhr
@Mo0gles: Die ifstream destructor wird beim Beenden aufgerufen is_file_exist und es wird den Stream schließen.
– Isaak
14. Juli 2015 um 9:13 Uhr
@Orwellophil return std::ifstream(fileName);
– Emlai
1. September 2017 um 22:34 Uhr
@emlai So sollte es sein return static_cast<bool>(std::ifstream(fileName));. Ohne den static_cast wird sich der Compiler beschweren.
– Benutzer4223038
17. Juni 2019 um 15:55 Uhr
Anhoppe
Für diejenigen, die Boost mögen:
boost::filesystem::exists(fileName)
oder seit ISO C++17:
std::filesystem::exists(fileName)
Jim Balter
Es hängt davon ab, wo sich die Dateien befinden. Sollen sie beispielsweise alle im selben Verzeichnis liegen, können Sie alle Verzeichniseinträge in eine Hash-Tabelle einlesen und dann alle Namen mit der Hash-Tabelle vergleichen. Dies könnte auf einigen Systemen schneller sein, als jede Datei einzeln zu prüfen. Der schnellste Weg, jede Datei einzeln zu überprüfen, hängt von Ihrem System ab … wenn Sie ANSI C schreiben, ist der schnellste Weg fopen weil es der einzige Weg ist (eine Datei kann existieren, aber nicht geöffnet werden, aber Sie möchten wahrscheinlich wirklich öffnen können, wenn Sie “etwas damit machen müssen”). C++, POSIX, Windows bieten alle zusätzliche Optionen.
Wenn ich schon dabei bin, lassen Sie mich auf einige Probleme mit Ihrer Frage hinweisen. Sie sagen, dass Sie den schnellsten Weg wollen und dass Sie Tausende von Dateien haben, aber dann fragen Sie nach dem Code für eine Funktion zum Testen einer einzelnen Datei (und diese Funktion ist nur in C++ gültig, nicht in C). Dies widerspricht Ihren Anforderungen, indem eine Annahme über die Lösung getroffen wird … ein Fall von das XY-Problem. Sie sagen auch “in Standard-c ++ 11 (oder) c ++ (oder) c” … die alle unterschiedlich sind, und dies entspricht auch nicht Ihrer Geschwindigkeitsanforderung … die schnellste Lösung würde darin bestehen, den Code an die anzupassen Zielsystem. Die Inkonsistenz in der Frage wird durch die Tatsache hervorgehoben, dass Sie eine Antwort akzeptiert haben, die systemabhängige Lösungen enthält und nicht Standard-C oder C++ ist.
Alexander Huszagh
Ohne andere Bibliotheken zu verwenden, verwende ich gerne das folgende Code-Snippet:
boost::filesystem
scheint zu gebrauchenstat()
. (Ausgehend von der Dokumentation.) Ich glaube nicht, dass Sie für FS-Aufrufe viel schneller arbeiten können. Der Weg, um das, was Sie tun, schnell zu machen, besteht darin, „das Betrachten von Tausenden von Dateien zu vermeiden“.– Millielch
8. Oktober 2012 um 1:15 Uhr
TOCTOU Frage: Woher wissen Sie, dass die Datei zwischen Ihrer Prüfung vonexists() und Ihrer „etwas dagegen tun“?
– Pilkrähe
8. Oktober 2012 um 1:16 Uhr
@pilcrow Guter Punkt, aber es gibt eine ziemlich breite Palette von Anwendungen, die nicht so viel Korrektheit erfordern. Z.B
git push
macht sich wahrscheinlich nicht die Mühe, sicherzustellen, dass Sie den Arbeitsbaum nach der anfänglichen schmutzigen Prüfung nicht berühren.– Millielch
8. Oktober 2012 um 1:27 Uhr
„Mir fällt keine C/C++-Implementierung ein, die das nicht hätte“ – Windows bietet keine POSIX-Umgebung.
– Jim Balter
8. Oktober 2012 um 1:58 Uhr
Mögliches Duplikat von std::ofstream, prüfen Sie vor dem Schreiben, ob die Datei existiert
– MDXF
27. Februar 2017 um 4:17 Uhr