642 Stimmen

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

Ich möchte den schnellsten Weg finden, um zu prü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 prüfen, ob sie alle existieren. Was kann ich anstelle von /* SOMETHING */ in der folgenden Funktion?

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

0voto

Steve Summit Punkte 37650

Der schnellste und sicherste Weg, auf das Vorhandensein von Dateien zu testen, ist es, überhaupt nicht separat/explizit darauf zu testen. Das heißt, versuchen Sie, eine Möglichkeit zu finden, die gewöhnliche

if(exists(file)) {                           /* point A */
    /* handle existence condition */
    return;
}

do_something_with(file);                     /* point B */

mit dem verbesserten

r = do_something_with_unless_exists(file);

if(r == 0)
    success;
else if(errno == EEXIST)
    /* handle existence condition */
else
    /* handle other error */

Dies ist nicht nur schneller, sondern eliminiert auch die Rennbedingung (konkret: " TOC/TOU "), die der ersten Lösung innewohnt, nämlich die Möglichkeit, dass die Datei zwischen Punkt A und Punkt B zustande kommt.

Die zweite Lösung setzt natürlich voraus, dass es einen atomaren Weg gibt, die do_something_with_unless_exists Betrieb. Oft gibt es einen Weg, aber manchmal muss man ihn erst suchen.

  • Erstellen einer Datei: Aufruf open() con O_CREAT y O_EXCL .

  • Erstellen einer Datei in reinem C, wenn Sie C11 haben: Aufruf fopen() con "wx" . (Ich habe erst gestern davon erfahren.)

  • Ein Verzeichnis erstellen: einfach anrufen mkdir() und prüfen auf errno == EEXIST danach.

  • Erwerb einer Sperre: Jedes brauchbare Sperrsystem verfügt bereits über ein atomares Primitiv zum Erwerb der Sperre, solange niemand sonst sie hat.

(Es gibt noch andere, aber das sind die, die mir gerade einfallen.)

[Fußnote: In den frühen Tagen von Unix gab es keine speziellen, dedizierten Einrichtungen, die gewöhnlichen Prozessen zur Verfügung gestellt wurden, um Sperren einzurichten. Wenn Sie also einen Mutex einrichten wollten, wurde dies typischerweise durch die Erstellung eines bestimmten leeren Verzeichnisses implementiert, da die mkdir syscall war schon immer in der Lage, auf der Grundlage der vorherigen Existenz oder Nichtexistenz zu scheitern oder erfolgreich zu sein, und zwar atomar].

-1voto

Juan Carlos Punkte 101

Erkennen, ob eine Datei in Windows existiert.

bool DoesExistFile(std::wstring filePath)
{
    bool result = true;

    HANDLE fileHandle = CreateFile(
        filePath.c_str(),
        GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    if ((fileHandle != NULL) && (fileHandle != INVALID_HANDLE_VALUE))
        CloseHandle(fileHandle);
    else
    {
        DWORD error = GetLastError();

        if ((error == ERROR_FILE_NOT_FOUND) || (error == ERROR_PATH_NOT_FOUND))
            result = false;
    }

    return result;
}

-6voto

miksiii Punkte 2398

Obwohl es mehrere Möglichkeiten gibt, dies zu tun, wäre die effizienteste Lösung für Ihr Problem wahrscheinlich die Verwendung einer der vordefinierten Methoden von fstream wie gut() . Mit dieser Methode können Sie überprüfen, ob die von Ihnen angegebene Datei existiert oder nicht.

fstream file("file_name.txt");

if (file.good()) 
{
    std::cout << "file is good." << endl;
}
else 
{
    std::cout << "file isnt good" << endl;
}

Ich hoffe, Sie finden dies nützlich.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X