it-swarm.com.de

C++: Dies ist die beste Methode, um das Vorhandensein von Dateien auf Windows-Plattformen zu überprüfen

Mögliches Duplizieren:
Wie können wir überprüfen, ob eine Datei vorhanden ist oder das Win32-Programm nicht verwendet?

Welches ist die beste Methode, um das Vorhandensein von Dateien zu prüfen:

Option 1:

GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(0xffffffff == GetFileAttributes("C:\\MyFile.txt"))
{
    //File not found
}

Option 2:

std::string fileName("C:\\MyFile.txt" );
ifstream fin( fileName.c_str() );

if( fin.fail() )
{
    //File not found
}

Wenn Sie denken, dass Option 1 die bessere Methode ist, können Sie mir sagen, wie Sie 0xffffffff als Konstante definieren (ich möchte #define nicht verwenden).

Vielen Dank

15

Beachten Sie, dass GetFileAttributes () aus anderen Gründen als fehlendem Vorhandensein fehlschlagen kann (beispielsweise Probleme mit Berechtigungen). Ich würde den Fehlercode auf Robustheit überprüfen:

GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes("C:\\MyFile.txt") && GetLastError()==ERROR_FILE_NOT_FOUND)
{
    //File not found
}
18
zdan

Hier sind zwei Dinge zu beachten:

  1. Die Überprüfung, ob die Datei über ihre Attribute vorhanden ist, ist möglicherweise um viele Größenordnungen schneller. Wenn eine Datei auf einem "langsamen" Dateisystem vorhanden ist (Band, Netzwerkspeicher, CD usw.), wird beim Öffnen der Datei ein tatsächlicher Rundgang zum Dateispeicherort durchgeführt. Die Dateiattribute hingegen werden von den Dateisystemtreibern abgefragt und zwischengespeichert, wenn das Verzeichnis abgefragt wird. Das Prüfen der Dateiattribute verursacht einen einmaligen Aufzählungsaufwand für die Aufzählung der Verzeichnisse, was weit weniger Roundtrips bedeutet. Dies kann eine erhebliche Einsparung bedeuten, wenn mehrere "langsam" sind. Dateien werden geprüft.

  2. Die Dateiattribute zeigen jedoch lediglich an, dass die Datei zum Zeitpunkt des Aufrufs vorhanden war. Die Datei kann gelöscht werden oder Sie haben möglicherweise keine Zugriffsberechtigungen. Wenn Sie versuchen, die Datei trotzdem zu öffnen, sollten Sie auf die Prüfung der Dateiattribute verzichten und die Datei tatsächlich öffnen.

8
Chris Becke

Wenn Sie nur auf Windows abzielen, ist Option 1 eindeutig das bessere der beiden. Die Konstante, nach der Sie suchen, ist in den Windows-Headern bereits vorhanden - sie heißt INVALID_FILE_ATTRIBUTES.

5
casablanca

Wie wäre es mit dem Boost?

if (!boost::filesystem::exists("C:\\MyFile.txt"))
{
    ...
}

http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm

5
Inverse

Die Option only robust, um zu prüfen, ob eine Datei vorhanden ist, besteht darin, zu versuchen, sie zu öffnen, und zu überprüfen, ob sie erfolgreich ist oder fehlschlägt.

Jede andere Methode ist eine potenzielle Race-Bedingung. Zum Beispiel kann GetFileAttributes Ihnen sagen, ob eine Datei vorhanden ist wenn Sie die Funktion aufgerufen haben . Dies ist jedoch nicht dasselbe, als ob sie existiert, wenn Sie versuchen, sie zu öffnen. Möglicherweise wurde es in der Zwischenzeit gelöscht (oder erstellt).

4
jalf

Ich würde den ersten vorziehen. Die zweite prüft, ob die Datei geöffnet werden kann, während eine Datei möglicherweise vorhanden ist, ohne dass Sie die Berechtigung zum Öffnen haben. 

Sie können die Konstante INVALID_FILE_ATTRIBUTES verwenden. 

3
GolezTrol

Ich möchte auch bestätigen, dass die Zeichenfolge kein Verzeichnis ist:

DWORD attr = GetFileAttributes(file);
if(attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY))
    return false;   //  not a file
return true;
2
sean e

Ich würde mich wegen der Plattformunabhängigkeit für die Verwendung der iostream entscheiden. Sie können zwar nur auf Windows abzielen, aber die Verwendung plattformunabhängiger Bibliotheken ist nie schlecht. Wenn Sie ein großes Projekt aufbauen, wissen Sie nie, was die nächste Phase mit sich bringen wird.

Ich bin nicht sicher, ob der obige Code der beste (oder korrekte) Weg ist, um das Vorhandensein von Dateien zu überprüfen. Versuchen Sie this :

ifstream f;
f.open(str);

if (f.is_open()) {
  // read file
}

Damals hatten wir nur OpenFile (und wir waren dankbar)

OFSTRUCT of = {0};
of.cBytes = sizeof(of);

HFILE hf = ::OpenFile("c:\\windows\\write.exe",&of,OF_EXIST);

if(hf > 0)
    printf("file exists"); 

return 0;
2
weloytty

Es gibt eine Nice-Shell-Utility-Funktion dafür, PathFileExists .

2
Ofek Shilon
#include <iostream>
#include <windows.h>
using namespace std;

bool FileExists(const TCHAR *fileName)
{
    DWORD       fileAttr;

    fileAttr = GetFileAttributes(fileName);
    if (0xFFFFFFFF == fileAttr && GetLastError()==ERROR_FILE_NOT_FOUND)
        return false;
    return true;
}

int main(int argc, char *argv[])
{


    if ( FileExists("testtt.txt"))
    {
      cout << "File exists \n";
    }
    else
    {
        cout << "File does not exist \n";

    }


  return 0;
}
0