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#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    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

  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 : 43
    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
    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 Expert Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    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êêêêêêêêêêê

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    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 Expert Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    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.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    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

+ 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