web-dev-qa-db-fra.com

Comment vérifier si un fichier existe avant de créer un nouveau fichier

Je souhaite entrer du contenu dans un fichier, mais je voudrais d'abord vérifier si un fichier portant le nom que je souhaite créer existe. Si c'est le cas, je ne souhaite créer aucun fichier, même s'il est vide. 

Ma tentative

bool CreateFile(char name[], char content[]){
     std::ofstream file(name);
     if(file){
         std::cout << "This account already exists" << std::endl;
        return false;
     }
     file << content;
     file.close();
     return true;
}

Est-il possible de faire ce que je veux?

27
Lion King

En supposant que l’opération n’est pas atomique, vous pouvez faire:

if (std::ifstream(name))
{
     std::cout << "File already exists" << std::endl;
     return false;
}
std::ofstream file(name);
if (!file)
{
     std::cout << "File could not be created" << std::endl;
     return false;
}
... 

Notez que cela ne fonctionne pas si vous exécutez plusieurs threads essayant de créer le même fichier et n'empêchera certainement pas un second processus d'interférer avec la création du fichier car vous avez TOCTUI problèmes. [Nous vérifions d'abord si le fichier existe, puis nous le créons - mais quelqu'un d'autre aurait pu le créer entre le contrôle et la création - si cela est essentiel, vous devrez faire autre chose, ce qui n'est pas portable]. 

Un autre problème est que si vous disposez d'autorisations telles que le fichier n'est pas lisible (nous ne pouvons donc pas l'ouvrir en lecture) mais qu'il est accessible en écriture, il écrasera le fichier. 

Dans la plupart des cas, aucune de ces choses n'a d'importance, car tout ce qui vous préoccupe, c'est de dire à quelqu'un que "vous avez déjà un fichier comme celui-ci" (ou quelque chose du genre) dans une approche "au mieux". 

25
Mats Petersson

vous pouvez également utiliser Boost.

 boost::filesystem::exists( filename );

cela fonctionne pour les fichiers et les dossiers. 

Et vous aurez une implémentation proche de quelque chose de prêt pour C++ 14 dans laquelle le système de fichiers devrait faire partie du STL (voir ici ).

13
alexbuisson

Essayez ceci (copie copiée de Erik Garrison: https://stackoverflow.com/a/3071528/575530 )

#include <sys/stat.h>

bool FileExists(char* filename) 
{
    struct stat fileInfo;
    return stat(filename, &fileInfo) == 0;
}

stat renvoie 0 si le fichier existe et -1 sinon.

7
dumbledad

Essayer

ifstream my_file("test.txt");
if (my_file)
{
 // do stuff
}

De: Comment vérifier si un fichier existe et est lisible en C++?

ou vous pouvez utiliser les fonctions de boost.

7
CBIII

A partir de C++ 17, il y a:

if (std::filesystem::exists(pathname)) {
   ...
6
James Hirschorn

J'ai jeté un coup d'œil autour de moi et la seule chose que je trouve est l'utilisation de l'appel système open. C’est la seule fonction que j’ai trouvée qui vous permet de créer un fichier d’une manière qui échouera s’il existe déjà.

#include <fcntl.h>
#include <errno.h>

int f=open(filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (f < 0) {
  /* file exists or otherwise uncreatable
     you might want to check errno*/
}else {
  /* File is open to writing */
}

Notez que vous devez donner des autorisations depuis la création d'un fichier.

Cela supprime également toutes les conditions de course qui pourraient exister.

2
rabensky

C++ 17, multiplate-forme: Utilisation de std::filesystem::exists et std::filesystem::is_regular_file .

#include <filesystem> // C++17
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;

bool CreateFile(const fs::path& filePath, const std::string& content)
{
    try
    {
        if (fs::exists(filePath))
        {
            std::cout << filePath << " already exists.";
            return false;
        }
        if (!fs::is_regular_file(filePath))
        {
            std::cout << filePath << " is not a regular file.";
            return false;
        }
    }
    catch (std::exception& e)
    {
        std::cerr << __func__ << ": An error occurred: " << e.what();
        return false;
    }
    std::ofstream file(filePath);
    file << content;
    return true;
}
int main()
{
    if (CreateFile("path/to/the/file.ext", "Content of the file"))
    {
        // Your business logic.
    }
}
0
Roi Danton

Je viens de voir ce test:

bool getFileExists(const TCHAR *file)
{ 
  return (GetFileAttributes(file) != 0xFFFFFFFF);
}
0
Racky