Wie können wir überprüfen, ob eine Datei vorhanden ist oder nicht, indem Sie das Win32-Programm verwenden?

74

Wie können wir überprüfen, ob eine Datei vorhanden ist oder nicht, wenn Sie ein Win32-Programm verwenden? Ich arbeite für eine Windows Mobile App.

Krishnan
quelle

Antworten:

26

Sie können anrufen FindFirstFile.

Hier ist ein Beispiel, das ich gerade angeklopft habe:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int fileExists(TCHAR * file)
{
   WIN32_FIND_DATA FindFileData;
   HANDLE handle = FindFirstFile(file, &FindFileData) ;
   int found = handle != INVALID_HANDLE_VALUE;
   if(found) 
   {
       //FindClose(&handle); this will crash
       FindClose(handle);
   }
   return found;
}

void _tmain(int argc, TCHAR *argv[])
{
   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Looking for file is %s\n"), argv[1]);

   if (fileExists(argv[1])) 
   {
      _tprintf (TEXT("File %s exists\n"), argv[1]);
   } 
   else 
   {
      _tprintf (TEXT("File %s doesn't exist\n"), argv[1]);
   }
}
Preet Sangha
quelle
4
Halb korrigiert. Sie müssen nach FILE_ATTRIBUTE_DIRECTORY suchen.
David Heffernan
2
Weitere Antworten finden Sie in anderen Antworten. Außerdem wird der Code nicht einmal so kompiliert, wie er ist, da argv [1] in fileExists () verwendet wird.
Christian Aichinger
3
Schlechte Lösung; GetFileAttributes()ist viel besser.
Trojanfoe
2
GetFileAttributesist ein Einzeiler
Matt Clarkson
4
Angenommen file = "*", dies könnte zurückgegeben werden, trueselbst wenn keine Datei mit dem Namen *
Felix Dombek
207

Verwenden Sie GetFileAttributesdiese Option, um zu überprüfen, ob das Dateisystemobjekt vorhanden ist und kein Verzeichnis ist.

BOOL FileExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES && 
         !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

Kopiert von Wie überprüfen Sie, ob unter Windows in C ein Verzeichnis vorhanden ist?

Zach Burlingame
quelle
5
+1 wegen eines kurzen Codebeispiels. Codebeispiele sparen Zeit, um loszulegen.
Nalply
Ich möchte darauf hinweisen, dass Ihre Funktion bool und nicht BOOL zurückgibt.
Marius Bancila
Für C ++ ja, für C ist es ein BOOL
Zach Burlingame
Bietet dies auch die beste Leistung bei der Überprüfung der Dateiexistenz?
Bitterblue
1
@Bitterblue: Ja, das ist so schnell, wie ich finden konnte.
Cameron
37

Sie können die Funktion nutzen GetFileAttributes. Es wird zurückgegeben, 0xFFFFFFFFwenn die Datei nicht vorhanden ist.

Codaddict
quelle
16
Interessante Geschichte auf GetFileAttributes und warum es die bevorzugte Methode in Windows-Code von Raymond Chen ist: blogs.msdn.com/b/oldnewthing/archive/2007/10/23/5612082.aspx
Zach Burlingame
2
Sie müssen überprüfen, ob das Objekt ein Verzeichnis ist.
David Heffernan
8
Tatsächlich wird zurückgegeben, INVALID_FILE_ATTRIBUTESwenn die Datei nicht vorhanden ist. Auf 64-Bit könnte es sein 0xFFFFFFFFFFFFFFFF.
Andreas Spindler
7
@AndreasSpindler, Da der Rückgabetyp ist, DWORDwie er zurückgeben kann 0xFFFFFFFFFFFFFFFF?
Ajay
Aktualisierter Link zu Raymond Chens Blog: devblogs.microsoft.com/oldnewthing/20071023-00/?p=24713
Ray
18

Wie wäre es einfach:

#include <io.h>
if(_access(path, 0) == 0)
    ...   // file exists
Pierre
quelle
Pierre Wie haben Sie diese Funktion gefunden? irgendeine Referenz?
Buddhika Chaturanga
2
@Buddhika Chaturanga Ich habe es in den 80ern in Borland Turbo C verwendet. Dies war die einzige Möglichkeit, vor dem Züchter "CreateFile" das Vorhandensein einer Datei zu überprüfen. Es ist in der Visual Studio-Dokumentation vergraben.
Pierre
9

Eine weitere Option: 'PathFileExists' .

Aber ich würde wahrscheinlich mitgehen GetFileAttributes.

Adrian McCarthy
quelle
2
Darüber hinaus PathFileExistserfordert die Verwendung von "Shlwapi.dll" (die in einigen Windows-Versionen nicht verfügbar ist) und ist etwas langsamer als GetFileAttributes.
Bitterblue
Es sagt Ihnen jedoch nicht, ob eine Datei oder ein Verzeichnis vorhanden war.
Jonathan Wood
Übrigens ist PathFileExists nur ein Wrapper für GetFileAttributes mit zusätzlichem SetErrorMode-Wrapper (SEM_FAILCRITICALERRORS).
Alex
0

Sie können versuchen, die Datei zu öffnen. Wenn es fehlgeschlagen ist, bedeutet dies, dass es in den meisten Fällen nicht vorhanden ist.

Fanzhou
quelle
Ich würde mit CreateFile -> CloseHandle gehen. am einfachsten und billigsten.
Arbeitsschutz
4
Das Öffnen einer Datei kann auch fehlschlagen, wenn die Dateien vorhanden sind, der Benutzer jedoch nicht über ausreichende Berechtigungen zum Öffnen der Datei verfügt. Heutzutage ist das eine sehr häufige Situation.
JackLThornton
Ganz zu schweigen davon, dass es nicht das billigste ist, da sich die Datei auf einer Netzwerkfreigabe befinden kann, wodurch die Latenz für jeden Anruf erhöht wird und Sie mit CloseHandle zwei Anrufe anstelle von einem haben.
Igor Levicki
-2

Ein weiterer allgemeinerer Weg ohne Windows:

static bool FileExists(const char *path)
{
    FILE *fp;
    fpos_t fsize = 0;

    if ( !fopen_s(&fp, path, "r") )
    {
        fseek(fp, 0, SEEK_END);
        fgetpos(fp, &fsize);
        fclose(fp);
    }

    return fsize > 0;
}
Alturis
quelle
Wenn Sie fopen et al. Sie können auch einfach verwenden _access(0).
Rob K
1
@RobK Dies hat den kleinen Vorteil, plattformübergreifend zu sein, _access jedoch nicht. Das eigentliche Problem ist, dass es zurückgibt, dass keine Dateien mit der Länge Null existieren ...
Perkins
fopen_s ist Microsoft-spezifisch und zusätzlich zu 0-Byte-Dateien, die durch diesen fehlerhaften Code als nicht vorhanden deklariert werden, schlägt es auch bei Dateien fehl, die nicht geöffnet werden können (Berechtigungen, Freigabe).
Igor Levicki