Comment faire pour vérifier si le fichier existe en C++ dans un portable?
Actuellement, je utiliser ce code pour vérifier si le fichier existe sur Windows
et POSIX
-compatible avec des Systèmes d'exploitation (Linux, Android, MacOS, iOS, BlackBerry 10):
bool FileExist( const std::string& Name )
{
#ifdef OS_WINDOWS
struct _stat buf;
int Result = _stat( Name.c_str(), &buf );
#else
struct stat buf;
int Result = stat( Name.c_str(), &buf );
#endif
return Result == 0;
}
Questions:
- Fait ce code avez des pièges? (peut-être un OS où il ne peut pas être compilé)
- Est-il possible de le faire dans un véritable mobiles à l'aide de C/C++ de la bibliothèque standard?
- Comment l'améliorer? Recherche pour l'exemple canonique.
Quel est le but de vérifier s'il existe, par exemple, allez-vous ouvrir le fichier s'il existe, ou imprimer un message d'erreur ou quelque chose d'autre?
Il devrait fonctionner correctement. Précisément je voudrais vérifier pour Windows et POSIX avec la valeur par défaut étant quelque chose de POSIX. Vous devriez probablement vous avez un projet spécifique OS définir en tant que bien, comme ces noms eux-mêmes peuvent changer d'un système à l'autre.
l'ouverture d'un fichier est une mauvaise idée - il peut exister, mais ouvert par un autre processus, dans un partage.
J'ai utilisé un accès pour tester l'existence. Je n'ai aucune idée si c'est mieux. En fait, je pense qu'il est plus facile comme vous l'avez fait. Exemple: si (l'accès("fichier", F_OK) == 0) ... Il peut être fait sur windows et linux.
il ressemble à un potentiel fosse de l'automne. Pourriez-vous résumer ça comme réponse?
Il devrait fonctionner correctement. Précisément je voudrais vérifier pour Windows et POSIX avec la valeur par défaut étant quelque chose de POSIX. Vous devriez probablement vous avez un projet spécifique OS définir en tant que bien, comme ces noms eux-mêmes peuvent changer d'un système à l'autre.
l'ouverture d'un fichier est une mauvaise idée - il peut exister, mais ouvert par un autre processus, dans un partage.
J'ai utilisé un accès pour tester l'existence. Je n'ai aucune idée si c'est mieux. En fait, je pense qu'il est plus facile comme vous l'avez fait. Exemple: si (l'accès("fichier", F_OK) == 0) ... Il peut être fait sur windows et linux.
il ressemble à un potentiel fosse de l'automne. Pourriez-vous résumer ça comme réponse?
OriginalL'auteur Sergey K. | 2013-08-19
Vous devez vous connecter pour publier un commentaire.
Parce que le C++ est aussi marqué, je voudrais utiliser
boost::filesystem
:Derrière les coulisses
Apparemment, boost est à l'aide de
stat
sur POSIX etDWORD attr(::GetFileAttributesW(FileName));
sur Windows (Note: j'ai extrait les parties pertinentes du code ici, il se pourrait que j'ai fait quelque chose de mal, mais cela devrait être).En gros, en plus de la valeur de retour, boost est la vérification de errno valeur afin de vérifier si le fichier n'existe pas vraiment, ou votre stat a échoué pour une raison différente.
not_found_error
est défini séparément pour Windows et pour POSIX:Windows:
POSIX:
Peut-être que vous pouvez étendre votre réponse en expliquant ce qui est à l'intérieur de
boost::filesystem::exists
? Il peut être une bonne réponse.Va le faire, merci.
L'intérieur est similaire à votre code, avec des implémentations différentes pour différentes plates-formes. La bibliothèque (qui est due à devenir une partie de la bibliothèque standard de l'année prochaine) fournit un portable interface pour que la malveillance.
Ajout de la description!
OriginalL'auteur Nemanja Boric
Je perosnally comme de juste essayer d'ouvrir le fichier:
devrait fonctionner sur tout ce qui a des fichiers [n'est pas requis par la norme C++] et puisque c'est à l'aide de C++
std::string
, je ne vois pas pourquoistd::ifstream
devrait être un problème.Je ne suis pas sûr qu'il y est de toute façon c'est 100% infaillible - le fichier peut également exister à l'instant, et supprimé la prochaine fois que ce processus arrive à terme. Ou il peut appartenir à un autre utilisateur, de sorte que nous n'avons pas de droits pour ouvrir (ou
stat
, etc). Tout "le fichier existe déjà" la méthode est consultatif, au mieux. Si la connaissance de savoir s'il existe, c'est dans le but de "ne pas sauvegarder sur un fichier existant", puis impossibilité d'ouvrir le fichier n'est pas un problème, parce que vous ne pouvez pas ouvrir le fichier pour l'écriture d'une ligne ou trois plus tard [de côté de la race conditions, bien sûr - par n'importe quelle méthode qui sera mis à l'].Mais la question était de savoir comment améliorer le code existant. Votre code supprime
#ifdef
mais ajoute une autre hypothèse. Ce n'est pas une amélioration, c'est un compromis.Il s'agit d'un compromis - il améliore la portabilité et supprime une dépendance sur le système ayant
stat
ou_stat
(dont certains OS peut-être pas).Pouvez-vous expliquer dans quelles circonstances le "faux négatif" de "le fichier est ouvert par un autre processus" est un gros problème?
OriginalL'auteur Mats Petersson
Result == 0
"saute"ENAMETOOLONG
,ELOOP
, des erreurs, etc. comme par cetteJe peux penser de ceci :
ENAMETOOLONG
chemin d'accès est trop long:-Dans de nombreux cas ,au cours d'une analyse récursive, le sous-dossier/les répertoires de continuer à croître, si le chemin d'accès est "trop" de temps cela peut entraîner dans cette erreur, mais le fichier n'existe !
Cas similaires pourraient se produire avec d'autres trop d'erreurs.
Aussi,
Comme par cette,
Je'ld préfèrent utiliser la surcharge
boost::filesystem::exists
méthodebool exists(const path& p, system::error_code& ec) noexcept;
Pas sûr, peut-être que nous pouvons essayer de changer de répertoire sur chaque réapparaît, puis de lancer une analyse.
Voir comment stimuler fait - pour l'essentiel - en plus de la valeur de retour, vous devez vérifier le dernier code d'erreur de l'ensemble.
OriginalL'auteur P0W