Je surveille un dossier pour les nouveaux fichiers et devez les traiter. Le problème est que l'ouverture de fichier occasionnelle échoue, car le système n'a pas fini de copier. P>
Quelle est la bonne façon de tester si le fichier est terminé la copie? p>
Clarification: Je n'ai pas d'autorisations d'écriture dans le dossier / fichiers et je ne peux pas contrôler le processus de copie (c'est l'utilisateur). P>
9 Réponses :
Une approche que je prends toujours est de créer un fichier à la fin de ma copie / transfert nommé "Token.txt" sans contenu. L'idée est que ce fichier sera créé à la fin de l'opération de transfert, vous pouvez donc surveiller cette création de fichier et lorsque ce fichier est créé, vous commencez à travailler avec vos fichiers. N'oubliez pas d'effacer ce fichier de jeton toujours lorsque vous commencez à traiter vos fichiers. P>
Mais si le compte d'utilisateur n'a pas le droit de supprimer des fichiers dans le serveur, cette approche n'aurait aucune utilité.
Ne pense pas que l'extraire attend un processus de copie qu'il contrôle lui-même. Alors, il n'y aurait pas de fichier jeton, non?
Je pense que vous ne pouvez pas dire s'il a ou non accès / contrôle sans processus sans plus de détails. C'est comme un brainstorming où tout le monde donne des intrants.
Vous devez également couvrir des cas tels que: le fichier est utilisé par un autre programme, le fichier a été supprimé (copie n'a pas réussi) etc. P>
Utilisez une manipulation exceptionnelle étendue pour couvrir tous les cas importants pouvant survenir. P>
Pas sûr de "la bonne façon", mais vous pouvez utiliser l'outil de surveillance ( FileSystemwatcher Code> Je suppose) pour remplir une file d'attente interne que vous utilisez pour le traitement différé. Ou mieux encore: il suffit d'utiliser une file d'attente pour placer des fichiers à l'écart ouvert, vous pouvez donc les réessayer plus tard. P>
Si vous utilisez FileSystemwatcher i Don Il faut penser qu'il y a une solution robuste à ce problème. Une approche serait essayer / attraper / réessayer plus tard. P>
Cela dépend, une boucle de réessation est probablement la meilleure que vous puissiez faire, si vous n'avez aucun contrôle sur le processus de copie. p>
Si vous avez le contrôle: p>
Je pense que le seul moyen sûr de le faire est d'ouvrir le fichier exclusivement et d'attraper une exception spécifique. Je déteste généralement en utilisant des exceptions pour la logique d'application normale, mais j'ai peur de ce scénario, il n'y a pas d'autre moyen (au moins je ne l'ai pas trouvé encore):
public bool FileIsDone(string path) { try { using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None)) { } } catch(UnauthorizedAccessException) { return false; } return true; }
En fait, pour éviter les conditions de race, la seule solution sûre consiste à réessayer.
Si vous faites quelque chose comme: p> Vous risquez un autre processus de saut entre le moment de la garde et de la déclaration de fichier de processus. Quelle que soit la mise en œuvre de votre "attente de la disponibilité des fichiers", à moins que vous ne puissiez garantir que la post-déverrouillage, vous êtes le premier processus pour y accéder, vous pourriez pas em> être ce premier utilisateur. P> Ceci est plus probable que cela pourrait sembler à première vue, en particulier si plusieurs personnes regardent le fichier, et en particulier s'ils utilisent quelque chose comme l'observateur du système de fichiers. Cours, il n'est toujours pas particulièrement probable même alors ... p> p>
Les fichiers sont-ils gros?
Peut-être que vous pourriez essayer de calculer un checksum MD5 sur le fichier? P>
Si vous mettez le hachage MD5 dans le nom de fichier, vous pouvez la récupérer et essayer de recalculer la somme de contrôle sur le fichier. Lorsque le MD5 est une correspondance, vous pouvez supposer que le fichier est terminé. P>
Voici une boucle VB.NET que j'utilise. Il attend 2 secondes entre chaque chèque.
Dim donotcopy As Boolean = True While donotcopy = True Dim myFile As New FileInfo("Filetocopy") Dim sizeInBytes As Long = myFile.Length Thread.Sleep(2000) Dim myFile2 As New FileInfo("Filetocopy") Dim sizeInBytes2 As Long = myFile2.Length If sizeInBytes2 = sizeInBytes Then donotcopy = False End While
Bonne question! Quand j'ai eu ce problème, je viens d'ajouter System.threading.threading.thread.sleep (1000), mais je voudrais amour i> pour obtenir une meilleure solution (c'est juste si boiteux ...)
Avez-vous lu accès au fichier original, qui est copié?