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

C# Discussion :

VS2008 / .net / C# : composant FileSystemWatcher execute evenement en rafale


Sujet :

C#

  1. #1
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut VS2008 / .net / C# : composant FileSystemWatcher execute evenement en rafale
    salut,

    j'ai un petite question concernant le composant FileSystemWatcher .. je l'utilise pour surveiller les modifications en écriture des fichiers d'un répertoire ... comme il est prévu pour ceci, ca tombe bien
    "le but sera a terme d'avoir un "service" en tache de fond qui va sauvegarder automatiquement un fichier a chaque modif dans une archive RAR afin de garder une trace de toutes les modifications et de pouvoir facilement remonter a une ancienne version"

    le problème c'est que ce FileSystemWatcher exécute plusieurs fois de suite le même évènement pour le même fichier quand je sauvegarde mon fichier de test ... le nombre de déclenchement de l'évènement varie de 2 a 5 :
    Changed / test4.html / 22/09/2008 19:53:18
    Changed / test4.html / 22/09/2008 19:53:18
    Changed / test4.html / 22/09/2008 19:53:18
    Changed / test4.html / 22/09/2008 19:53:18
    par contre si je fais glisser un fichier dans le répertoire surveillé je n'ai bien qu'un seul déclenchement de l'évènement ...

    voici le code de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    private void Form1_Load(object sender, EventArgs e)
    {
        this.fileSystemWatcher1 = new FileSystemWatcher(@"E:\Mes images\_x");
        this.fileSystemWatcher1.EnableRaisingEvents = true;
        this.fileSystemWatcher1.IncludeSubdirectories = true;
     
        NotifyFilters filtre = NotifyFilters.LastWrite;
        this.fileSystemWatcher1.NotifyFilter = filtre;
     
        this.fileSystemWatcher1.Changed += new System.IO.FileSystemEventHandler(this.fileSystemWatcher1_Ecriture);
    }
     
     
    private void fileSystemWatcher1_Ecriture(object sender, System.IO.FileSystemEventArgs e)
    {
        if (File.Exists(e.FullPath)) {
            FileInfo file = new FileInfo(e.FullPath);
            Console.WriteLine(e.ChangeType + " / " + file.Name+" / "+file.LastWriteTime);
        } else if (Directory.Exists(e.FullPath)) {
            DirectoryInfo dir = new DirectoryInfo(e.FullPath);
            Console.WriteLine(e.ChangeType + " / " + dir.Name + " / " + dir.LastWriteTime);
        }
    }
    j'ai cherché/testé pour vérifier si le nombre de déclenchement avait un rapport avec la taille du fichier mais c'est non.
    le seul indice que j'ai pu trouver c'est en sauvegardant le fichier de test avec différents éditeur de texte, suivant l'éditeur le nombre de déclenchement change
    mes tests portent sur des fichiers HTML/TXT de 20Ko, je vois pas trop l'éditeur le sauvegarder en plusieurs fois, donc je comprends pas ce comportement

    vous avez une idée pour avoir qu'un seul déclenchement d'évènement lors de la sauvegarde/modification du fichier ?

    merci
    Le plus grand arbre est né d'une graine menue, une tour de neuf étages est partie d'une poignée de terre.
    Mon blog : http://web.codeur.free.fr

  2. #2
    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
    A mon avis c'est quand même lié à la taille des fichiers... en général on écrit pas un fichier entier d'une traite, on passe par des buffers (souvent 4 ou 8 ko). Donc à chaque fois qu'un nouveau buffer est écrit, le fichier est modifié et ça déclenche Changed.
    Quand tu reçois l'évènement, il faudrait tester si le fichier est encore ouvert : si oui, l'écriture n'est sans doute pas terminée, donc tu ignores l'évènement. Tu peux vérifier que le fichier est ouvert en essayant de l'ouvrir en lecture en mode exclusif (FileShare.None) : si ça lève une exception, c'est qu'il est ouvert.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
    {
        // Si le fichier est ouvert, on ne fait rien
        if (IsOpen(e.FullPath))
            return;
     
        // Sinon, on fait le traitement normal
    }
     
    private bool IsOpen(string filename)
    {
        FileStream fs = null;
        try
        {
            fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch(IOException)
        {
            return true;
        }
        finally
        {
            if (fs != null)
                fs.Close();
        }
        return false;
    }

  3. #3
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    salut tomlev


    j'ai bien vérifié si la taille du fichier avait un quelconque rapport et je suis absolument certain que non, exemple avec EditPlus 3 (mon éditeur de texte préféré) :
    -un fichier de 0 octets déclenche 3 fois l'évènement lors de sa sauvegarde
    -un fichier de 1 octet a 198 809 600 octets (198Mo) déclenche 4 fois l'évènement lors de sa sauvegarde

    pour notepad c'est toujours 2.


    j'ai aussi vérifié si la taille du fichier changeait entre chaque appel ... c'est négatif.

    j'ai donc utilisé un MD5 du fichier source pour le comparer a la destination et c'est la que j'ai pu vérifier que le 1er déclenchement de l'évènement correspond bien a l'écriture complète du fichier .... les autres déclenchements sont des échos ou un bug ??



    j'ai testé ta solution et elle a le mérite de fonctionner en partie quand je sauvegarde un fichier avec EditPlus, de temps en temps elle ne bloque (isOpen == true) que le 1er évènement, d'autres fois les 2ers et encore d'autres fois les 3 ers sur les 4 déclenchements au total
    par contre quand je sauvegarde avec le notepad, isOpen est toujours false si le fichier ne fait pas 0 octet

    il y a de quoi devenir chèvre ... bêêêêêêêêêêê
    Le plus grand arbre est né d'une graine menue, une tour de neuf étages est partie d'une poignée de terre.
    Mon blog : http://web.codeur.free.fr

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 155
    Points : 25 074
    Points
    25 074
    Par défaut
    ca depend du logiciel qui enregistre le fichier, chacun a sa technique

    le but est de gérer ca autrement
    quand l'évènement se déclenche, tu ajoutes le nom du fichier et l'heure dans une collection, puis tu démarres un timer (s'il n'est pas déjà démarré) de une ou deux secondes
    sur le tick du timer, tu parcours la collection à la recherche de fichiers dans ta collection dont la date que tu as mis avec date de plus d'une seconde

    ou alors un thread qui s'occupe de dépiler à la place du timer, ca fait plus propre
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    salut,

    ta soluce serait donc de faire une tempo entre le déclenchement de l'évènement et la classe qui va faire la sauvegarde ... c'est sur que ca reglerait le probleme mais je trouve pas ca infaillible, il peut trés bien avoir une autre sauvegarde pendant la tempo ... les modifs ne seront donc pas enregistrés, le risque est faible de faire modif+sauvegarde dans un écart de temps de 1sec sur le fichier mais il existe.
    Le plus grand arbre est né d'une graine menue, une tour de neuf étages est partie d'une poignée de terre.
    Mon blog : http://web.codeur.free.fr

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 155
    Points : 25 074
    Points
    25 074
    Par défaut
    c'est à toi de voir la tempo
    si les rafales sont toutes dans le meme centième de seconde, tu peux enregistrer au 10eme de seconde

    ca depend de ce qui peut enregistrer les fichiers aussi ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 112
    Points : 57
    Points
    57
    Par défaut
    Je suis aujourd'hui confronté à ce même problème.
    Une explication a-t-elle été trouvée?

    Merci

  8. #8
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    bienvenue dans la 3eme dimension mon ami

    j'ai du rajouter 8 tests différents pour zapper toutes les erreurs/bugs/bizarrerie de chaque programme qui peuvent sauvegarder des fichiers

    voici un petit programme que je me suis fait pour tester tous les comportements de FileSystemWatcher : http://www.developpez.net/forums/d62...diteur-vs2008/
    celui ci devrait bien t'aider dans tes tests !
    Le plus grand arbre est né d'une graine menue, une tour de neuf étages est partie d'une poignée de terre.
    Mon blog : http://web.codeur.free.fr

  9. #9
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    salut la 3ème dimension :

    Par rapport à votre problème avez vous essayé d'enlever du code ces 2 ligne?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    NotifyFilters filtre = NotifyFilters.LastWrite;
    this.fileSystemWatcher1.NotifyFilter = filtre;
    J'ai également travaillé sur les filesystemwatcher mais je n'ai jamais appliqué de notifyfilter. A mon avis, s'abonner fileSystemWatcher1.Changed suffit. j'ai essayé et il n'y a pas de problème chez moi.

    tiens nous au courant.
    Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

    N'oubliez pas de avant de
    Pas de question techniques par MP, c'est contre la philosophie du forum

  10. #10
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    dans ce cas tu n'as tout simplement aucun déclenchement ... j'ai du mal a comprendre comment tu peux encore avoir des déclenchements
    Le plus grand arbre est né d'une graine menue, une tour de neuf étages est partie d'une poignée de terre.
    Mon blog : http://web.codeur.free.fr

  11. #11
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    bonjour à tous,

    Je me permets de relancer ce sujet afin de vous affirmer que j'ai trouvé une solution mais partielle!!!

    Je viens d'avoir à faire à ce problème d'évènement qui s'execute seulement 2fois chez moi. J'ai cherché un peu et en mettant seulement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fileSystemWatcher1.NotifyFilter = System.IO.NotifyFilters.LastAccess;
    quand je modifie le fichier, il n'y a plus qu'un seul évènement qui me parviens. Je ne l'explique pas très bien mais mieu vaut ne rien dire que dire des co......s!!!
    En espérant que ça aidera les personnes qui rencontrerons cette difficulté à l'avenir.
    Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

    N'oubliez pas de avant de
    Pas de question techniques par MP, c'est contre la philosophie du forum

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

Discussions similaires

  1. [Composant] création d'evenement.
    Par Nicolos_A dans le forum Delphi
    Réponses: 9
    Dernier message: 04/06/2006, 07h27
  2. Réponses: 5
    Dernier message: 16/02/2006, 16h27
  3. [VB.NET][SharpDevelop]Composant Calendrier Outlook
    Par Emcy dans le forum Windows Forms
    Réponses: 6
    Dernier message: 21/10/2005, 10h29
  4. [vb.net][tab] comment empecher un evenement de se produire?
    Par graphicsxp dans le forum Windows Forms
    Réponses: 3
    Dernier message: 22/07/2005, 15h18
  5. [VB.NET] Liste composant
    Par borgfabr dans le forum Windows Forms
    Réponses: 4
    Dernier message: 12/04/2005, 18h09

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