Der schnellste Weg, um zu überprüfen, ob eine Datei mit Standard-C++/C++11,14,17/C vorhanden ist?

Lesezeit: 6 Minuten

Der schnellste Weg um zu uberprufen ob eine Datei mit
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?

inline bool exist(const std::string& name)
{
    /* SOMETHING */
}

  • 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

1646901612 227 Der schnellste Weg um zu uberprufen ob eine Datei mit
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.

#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>

inline bool exists_test0 (const std::string& name) {
    ifstream f(name.c_str());
    return f.good();
}

inline bool exists_test1 (const std::string& name) {
    if (FILE *file = fopen(name.c_str(), "r")) {
        fclose(file);
        return true;
    } else {
        return false;
    }   
}

inline bool exists_test2 (const std::string& name) {
    return ( access( name.c_str(), F_OK ) != -1 );
}

inline bool exists_test3 (const std::string& name) {
  struct stat buffer;   
  return (stat (name.c_str(), &buffer) == 0); 
}

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?

    – ilent2

    21. Februar 2014 um 2:38 Uhr


  • Sie können auch verwenden/testen en.cppreference.com/w/cpp/experimental/fs/exists ab kommendem Standard

    – Zahir

    22. August 2014 um 14:10 Uhr

Der schnellste Weg um zu uberprufen ob eine Datei mit
Vinzenz

Bemerkung: in C++14 und sobald die Dateisystem TS fertig gestellt und angenommen wird, wird die Lösung sein:

std::experimental::filesystem::exists("helloworld.txt");

und seit C++17 nur noch:

std::filesystem::exists("helloworld.txt");

  • 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++:

bool is_file_exist(const char *fileName)
{
    std::ifstream infile(fileName);
    return infile.good();
}

  • 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

Der schnellste Weg um zu uberprufen ob eine Datei mit
Anhoppe

Für diejenigen, die Boost mögen:

 boost::filesystem::exists(fileName)

oder seit ISO C++17:

 std::filesystem::exists(fileName)

1646901614 769 Der schnellste Weg um zu uberprufen ob eine Datei mit
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.

1646901615 651 Der schnellste Weg um zu uberprufen ob eine Datei mit
Alexander Huszagh

Ohne andere Bibliotheken zu verwenden, verwende ich gerne das folgende Code-Snippet:

#ifdef _WIN32
   #include <io.h> 
   #define access    _access_s
#else
   #include <unistd.h>
#endif

bool FileExists( const std::string &Filename )
{
    return access( Filename.c_str(), 0 ) == 0;
}

Dies funktioniert plattformübergreifend für Windows- und POSIX-kompatible Systeme.

1646901616 301 Der schnellste Weg um zu uberprufen ob eine Datei mit
O’Neil

Dasselbe wie von PherricOxide vorgeschlagen, aber in C

#include <sys/stat.h>
int exist(const char *name)
{
  struct stat   buffer;
  return (stat (name, &buffer) == 0);
}

  • .c_str() ist eine C++-Funktion. Ich kenne C++ nicht, also habe ich ein C-Äquivalent gepostet.

    – Ramón La Pietra

    29. Juli 2014 um 11:01 Uhr

987150cookie-checkDer schnellste Weg, um zu überprüfen, ob eine Datei mit Standard-C++/C++11,14,17/C vorhanden ist?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy