En gros, je voudrais vérifier si j'ai le droit d'ouvrir le fichier avant d'essayer de l'ouvrir; Je ne veux pas utiliser un try / catch pour cette vérification, sauf si je dois le faire. Y a-t-il une propriété d'accès aux fichiers que je peux vérifier à l'avance?
c#
.net
file-access
Horas
la source
la source
Réponses:
J'ai fait cela d'innombrables fois dans le passé, et presque chaque fois que je l'ai fait, j'avais même eu tort d'essayer.
Les autorisations de fichier (même l'existence de fichier) sont volatiles - elles peuvent changer à tout moment. Grâce à la loi de Murphy, cela inclut en particulier la brève période entre le moment où vous vérifiez le fichier et le moment où vous essayez de l'ouvrir. Un changement est encore plus probable si vous vous trouvez dans une zone où vous savez que vous devez d'abord vérifier. Pourtant, étrangement, cela ne se produira jamais dans vos environnements de test ou de développement, qui ont tendance à être assez statiques. Cela rend le problème difficile à repérer plus tard et facilite la mise en production de ce type de bogue.
Cela signifie que vous devez toujours être en mesure de gérer l'exception si les autorisations de fichier ou l'existence sont mauvaises, malgré votre vérification. Un code de gestion des exceptions est requis , que vous vérifiiez ou non les autorisations du fichier à l'avance. Le code de gestion des exceptions fournit toutes les fonctionnalités de vérification d'existence ou d'autorisations. De plus, alors que les gestionnaires d'exceptions comme celui-ci sont connus pour être lents, il est important de se rappeler que les E / S disque sont encore plus lentes ... beaucoup plus lentes ... et l'appel de la fonction .Exists () ou la vérification des autorisations forcera un déclenchement supplémentaire. le système de fichiers.
En résumé, une vérification initiale avant d'essayer d'ouvrir le fichier est à la fois redondante et inutile. Il n'y a pas d'avantage supplémentaire par rapport à la gestion des exceptions, cela nuira en fait, pas aider, vos performances, cela ajoute des coûts en termes de code supplémentaire qui doit être maintenu, et cela peut introduire des bogues subtils dans votre code. Il n'y a tout simplement aucun avantage à faire la vérification initiale. Au lieu de cela, la bonne chose ici est d'essayer simplement d'ouvrir le fichier et de mettre vos efforts dans un bon gestionnaire d'exceptions en cas d'échec. La même chose est vraie même si vous ne faites que vérifier si le fichier existe ou non. Ce raisonnement s'applique à toute ressource volatile.
la source
Astuce rapide pour quiconque vient ici avec un problème similaire:
Méfiez-vous des applications de synchronisation Web telles que DropBox. Je viens de passer 2 heures à penser que l'instruction "using" (Dispose pattern) est cassée dans .NET.
J'ai finalement réalisé que Dropbox lisait et écrivait continuellement des fichiers en arrière-plan, afin de les synchroniser.
Devinez où se trouve mon dossier Projets Visual Studio? Dans le dossier "My Dropbox" bien sûr.
Par conséquent, lorsque j'exécutais mon application en mode Débogage, les fichiers qu'elle lisait et écrivait étaient également continuellement accédés par DropBox pour être synchronisés avec le serveur DropBox. Cela a provoqué les conflits de verrouillage / accès.
Donc au moins je sais maintenant que j'ai besoin d'une fonction d'ouverture de fichier plus robuste (ie TryOpen () qui fera plusieurs tentatives). Je suis surpris que ce ne soit pas déjà une partie intégrée du cadre.
[Mettre à jour]
Voici ma fonction d'assistance:
la source
using
devra cependant être utilisé par l'appelant ...using
ne fonctionnera pas ici. À la fin du bloc d'utilisation,fs
sera forcé de se fermer. Vous donnerez à l'appelant un flux de fichiers FERME (si inutile)!Voici la solution que vous recherchez
cela crée une nouvelle autorisation de lecture basée sur la vue pour le chemin de tous les fichiers, puis vérifie si elle est égale à la lecture d'accès au fichier.
la source
Tout d'abord, ce que Joel Coehoorn a dit.
Aussi: vous devriez examiner les hypothèses qui sous-tendent votre désir d'éviter d'utiliser try / catch à moins que vous n'y soyez obligé. La raison typique pour éviter la logique qui dépend des exceptions (la création d'
Exception
objets fonctionne mal) n'est probablement pas pertinente pour le code qui ouvre un fichier.Je suppose que si vous écrivez une méthode qui remplit un
List<FileStream>
en ouvrant chaque fichier dans un sous-arbre de répertoire et que vous vous attendiez à ce qu'un grand nombre d'entre eux soit inaccessible, vous voudrez peut-être vérifier les autorisations de fichier avant d'essayer d'ouvrir un fichier afin de ne pas obtenir trop d'exceptions. Mais vous gérez toujours l'exception. De plus, il y a probablement quelque chose qui ne va pas dans la conception de votre programme si vous écrivez une méthode qui fait cela.la source
la source
la source
attempts
passé par ref? Ça n'a aucun sens. Les tests pour<=
au lieu de simplement==
.throw ex
c'est en fait la bonne chose à faire.