IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Comment distinguer un répertoire d'un fichier a partir des Events FileSystemWatcher


Sujet :

VB.NET

  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut Comment distinguer un répertoire d'un fichier a partir des Events FileSystemWatcher
    Bonjour a tous,
    Ça a l'air tout simple mais je galère sur ce problème :
    Je surveille un dossier avec le composant FileSystemWatcher et dans les événements myFsWatcher.Created, Changed, Renamed et Deleted je récupère un objet e du type FileSystemEventArgs ou System.IO.RenamedEventArgs.
    Dans chacun de ces événements j'ai besoin d'effectuer un traitement différent selon si la modification du dossier surveillé porte sur un fichier ou sur un répertoire.
    Savez vous comment faire pour savoir si la modification porte sur un répertoire ou sur un fichier a partir de l'objet e récupéré ?

    Merci beaucoup pour votre aide car je ne vois vraiment pas comment faire.

  2. #2
    Membre éclairé
    Homme Profil pro
    Technicien bio médical
    Inscrit en
    Décembre 2012
    Messages
    328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien bio médical
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2012
    Messages : 328
    Points : 768
    Points
    768
    Par défaut
    Bonjour,
    Vous pouvez le faire en utilisant la méthode Path.GetExtension()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    If String.IsNullOrEmpty(Path.GetExtension(e.FullPath)) Then
     
    End If
    Si le Path passé en paramètre à la méthode n'a pas d'extension, GetExtension() retourne String.Empty, c'est que c'est un dossier sinon un fichier.

    EDIT : En relisant MSDN, Path.HasExtension() est plus approprié

    Bon dev.
    est ton amis, MSDN est ton maître, pour le reste il y a Developpez.net. Pensez au au et

  3. #3
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Path.HasExtension renverra aussi True pour un dossier dont le nom contiendrait un "." (exemple un dossier Foo.Bar)

    Il serait sans doute plus utile de vérifier quels attributs a le fichier voir du cote de FileAttributes.Directory.
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Rainui Voir le message
    Si le Path passé en paramètre à la méthode n'a pas d'extension, GetExtension() retourne String.Empty, c'est que c'est un dossier sinon un fichier.
    Rien n'impose à un fichier d'avoir une extension, et rien n'interdit à un dossier d'en avoir une... tu peux très bien créer un fichier "toto" dans un dossier "titi.txt" si ça t'amuse.

    La solution est plutôt de tester les attributs comme proposé par Sehnsucht :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim isDirectory As Boolean = File.GetAttributes(path).HasFlag(FileAttributes.Directory)
    Par contre ça ne fonctionnera pas pour l'évènement Delete, puisque le fichier ou dossier n'existe plus...

  5. #5
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonjour et merci d'essayer de m'aider.
    En effet Path.HasExtension renvoie True si le répertoire contient un "."

    j'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Dim Fi As New FileInfo(e.FullPath)
    If Fi.Attributes = FileAttributes.Directory Then
    MessageBox.Show(String.Format("Répertoire : {0}", e.Name))
    Else
    MessageBox.Show(String.Format("Fichier : {0}", e.Name))
    End If
    Ça fonctionne sauf dans l’événement Deleted, en effet Fi.Attributes est égale a -1 quelque soit le chemin que l'on efface (répertoire ou fichier).

    Vous avez une idée pour que cela fonctionne pour tous les événements ?

  6. #6
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    Tu peux utiliser la propriété NotifyFilter pour filtrer les évènements venant des fichiers ou des dossiers. En gros tu fais 2 FileSystemWatcher, le premier pour recevoir les évènements pour les fichiers et le deuxième pour les dossiers

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    fileSystemWatcher1.NotifyFilter = NotifyFilters.FileName;
    fileSystemWatcher2.NotifyFilter = NotifyFilters.DirectoryName;

  7. #7
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Il faudrait vérifier mais il me semble que les chemins retournés par FileSystemWatcher ont un séparateur ("/" ou "\") à la fin lorsqu'il s'agit d'un dossier.

  8. #8
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci a vous tous d'essayer de m'aider, je ne pensais pas galérer autant sur ce petit détail.

    Il faudrait vérifier mais il me semble que les chemins retournés par FileSystemWatcher ont un séparateur ("/" ou "\") à la fin lorsqu'il s'agit d'un dossier.
    Hélas non, les chemins ne se terminent pas un séparateur.

    J'ai crée un objet DirectoryInfo et FileInfo dans chaque événements a la recherche d'une propriété sur chacun d'eux qui me permettrait de distinguer un répertoire d'un Dossier. A mon grand étonnement il n'y a rien qui différencie un répertoire d'un fichier sauf la propriété FileInfo.Attributes mais qui ne fonctionne pas dans l’événement Deleted comme dit avant.

    Il y aurait peut-être une solution avec la propriété FileInfo.Lenght, en effet si il s'agit d'un fichier celle-ci retourne la propriété Lenght de ce fichier et si il s'agit d'un répertoire celle-ci lève une exception donc une solution possible serait de placer le code dans un bloc Try/Catch et donc ceci uniquement dans l’événement Deleted.

    Après se pose une autre question car j'ai aussi le soucis de garder une application stable et réactive et je connais peu le comportement du FileSystemWatcher si les événements arrivent plus vite que l'application ne puisse les traiter. D’après ma petite expérience un bloc Try/Catch est relativement gourmand en ressources et j'ai aussi le choix avec la solution de meziantou en déclarant 2 FileSystemWatcher.

    Pour l'instant voila ou j'en suis, j'espère qu'il y a d'autres solutions encore inexplorées ou sinon je devrais choisir entre ces 2 solutions.
    Ça intéresserais beaucoup d'avoir votre avis.

  9. #9
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    Après se pose une autre question car j'ai aussi le soucis de garder une application stable et réactive et je connais peu le comportement du FileSystemWatcher si les événements arrivent plus vite que l'application ne puisse les traiter.
    Il y a un buffer de taille fixe (cf. FileSystemWatcher.InternalBufferSize). En cas de dépassement les changements en trop ne seront pas rapportés. Aucune exception ne sera levée. Il est possible de détecter ce cas de figure via l'événement "Error".

    D’après ma petite expérience un bloc Try/Catch est relativement gourmand en ressources
    Techniquement c'est la levée de l'exception qui est lente, et non pas son interception. Autrement dit "throw", pas "try / catch". L'impact des blocs catch en eux-mêmes est relativement négligeable.

    Il y aurait peut-être une solution avec la propriété FileInfo.Lenght
    Je ne vois pas comment FileInfo.Length pourrait fonctionner après la suppression du fichier. A moins d'utiliser un FileInfo créé au préalable et ayant cette information en cache. Or si tu gardes tes FileInfo il te suffit d'appeler Attributes avant la suppression des fichiers afin de forcer la mise en cache sur cette instance.

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    Il y aurait peut-être une solution avec la propriété FileInfo.Lenght, en effet si il s'agit d'un fichier celle-ci retourne la propriété Lenght de ce fichier et si il s'agit d'un répertoire celle-ci lève une exception donc une solution possible serait de placer le code dans un bloc Try/Catch et donc ceci uniquement dans l’événement Deleted.
    Comme l'a dit DonQuiche, ça ne règle rien : si le fichier n'existe plus, ça lèvera aussi une exception...

    Citation Envoyé par BasicZX81 Voir le message
    Après se pose une autre question car j'ai aussi le soucis de garder une application stable et réactive et je connais peu le comportement du FileSystemWatcher si les événements arrivent plus vite que l'application ne puisse les traiter.
    J'ai rencontré ce problème dans l'appli que je développe au boulot. La solution est de faire le moins de choses possible dans le gestionnaire d'évènement du FileSystemWatcher. Par exemple, tu les ajoutes juste à une collection, et tu traites cette collection sur un autre thread. Il vaut donc mieux choisir une collection qui supporte l'utilisation en multi-thread, par exemple ConcurrentQueue<T>.

    Sinon, pour distinguer les suppressions de dossier ou de fichier, la solution proposée par DonQuiche (2 watchers distincts avec des filtres différents) me semble pas mal...

  11. #11
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci beaucoup pour ces précisions.

    Comme l'a dit DonQuiche, ça ne règle rien : si le fichier n'existe plus, ça lèvera aussi une exception...
    En effet j'ai dit une bêtise, FileInfo.Lenght ne retourne pas la taille du fichier Deleted.

    Dans ce cas je vais déclarer 2 FileSystemWatcher.

  12. #12
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonjour je passe en résolu.
    Finalement j'ai pris le problème a l'envers en me disant que Microsoft avait certainement de bonnes raisons (comme souvent) de ne pas permettre de faire la distinction entre un dossier et un fichier dans l'événement Deleted (même si je ne suis pas entièrement d'accord). Quoi qu'il en soit, partant de cette hypothèse et en approfondissant la question j'ai pu m'en sortir en faisant exactement le même traitement pour les dossiers et les fichiers (au moins pour l’événement Deleted) au prix de quelques adaptations du code.
    Je vous remercie a tous pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/03/2014, 15h58
  2. Réponses: 8
    Dernier message: 13/02/2013, 00h35
  3. Réponses: 2
    Dernier message: 22/04/2010, 17h13
  4. Réponses: 2
    Dernier message: 07/12/2006, 15h18
  5. Comment copier un répertoire et ses fichiers?
    Par Mickey.jet dans le forum Delphi
    Réponses: 4
    Dernier message: 08/07/2006, 12h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo