web-dev-qa-db-fra.com

C++: Quelle est la meilleure méthode pour vérifier l'existence d'un fichier sur la plate-forme Windows

Duplicate possible:
Comment pouvons-nous vérifier si un fichier existe ou non avec le programme Win32?

Quelle est la meilleure méthode pour vérifier l’existence d’un fichier:

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
}

Aussi, si vous pensez que l'option 1 est la meilleure méthode, pouvez-vous me dire comment définir 0xffffffff en tant que constante (je ne souhaite pas utiliser #define)

Merci

15

Notez que GetFileAttributes () peut échouer pour des raisons autres que l'absence d'existence (problèmes d'autorisations, par exemple). Je voudrais ajouter une vérification sur le code d'erreur pour la robustesse:

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

Il y a deux choses à considérer ici:

  1. Vérifier si le fichier existe via ses attributs est potentiellement beaucoup plus rapide - Si un fichier existe sur un système de fichiers 'lent' - bande, stockage réseau, cd, etc., l'ouverture du fichier implique un aller-retour à l'emplacement du fichier. Les attributs de fichiers, quant à eux, sont interrogés et mis en cache par les pilotes du système de fichiers lorsque le répertoire est interrogé. Par conséquent, l'analyse des attributs de fichier implique un coût d'énumération de répertoire unique, ce qui signifie beaucoup moins de va-et-vient, ce qui peut représenter une économie importante si plusieurs opérations "lentes" les fichiers sont en cours de vérification.

  2. Cependant, les attributs de fichiers indiquent simplement que le fichier existait au moment où l'appel a été passé. Le fichier peut être supprimé ou vous ne pouvez pas avoir les autorisations pour y accéder. Si vous êtes sur le point d’essayer d’ouvrir le fichier de toute façon, il serait préférable de se passer de la vérification des attributs de fichier et d’essayer d’ouvrir le fichier.

8
Chris Becke

Si vous ne ciblez que Windows, l'option n ° 1 est clairement la meilleure des deux. En outre, la constante que vous recherchez existe déjà dans les en-têtes de Windows: elle s'appelle INVALID_FILE_ATTRIBUTES.

5
casablanca

Que diriez-vous d'utiliser boost?

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

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

5
Inverse

Le moyen only / pour vérifier si un fichier existe consiste à essayer de l'ouvrir et de voir s'il réussit ou échoue.

Any Une autre méthode est une condition de concurrence critique. Par exemple, GetFileAttributes peut vous dire si un fichier existait lorsque vous avez appelé la fonction , mais ce n'est pas la même chose que s'il existait lorsque vous essayez de l'ouvrir. Il a peut-être été supprimé (ou créé) entre-temps.

4
jalf

Je préférerais le premier. La seconde vérifie si le fichier peut être ouvert, alors qu'un fichier peut exister sans que vous ayez le droit de l'ouvrir. 

Vous pouvez utiliser la constante INVALID_FILE_ATTRIBUTES

3
GolezTrol

J'aime aussi confirmer que la chaîne n'est pas un répertoire:

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

Je choisirais d'utiliser iostream en raison de son indépendance de plate-forme. Certes, vous ne ciblez peut-être que Windows, mais utiliser des bibliothèques indépendantes de la plate-forme n’est jamais une mauvaise chose. Si vous construisez un grand projet, vous ne savez jamais ce que cette prochaine phase impliquera.

Je ne suis pas sûr que le code ci-dessus soit la meilleure (ou correcte) méthode pour vérifier l'existence d'un fichier. Essayez this :

ifstream f;
f.open(str);

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

De retour dans la journée, tout ce que nous avions était OpenFile (et nous étions reconnaissants)

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

Il existe une fonction utilitaire Nice Shell pour cela, 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
Software_Designer