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?
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".
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 ).
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.
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.
A partir de C++ 17, il y a:
if (std::filesystem::exists(pathname)) {
...
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.
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.
}
}
Je viens de voir ce test:
bool getFileExists(const TCHAR *file)
{
return (GetFileAttributes(file) != 0xFFFFFFFF);
}