Publié le 15/05/2013
Auteur Axel
Réseaux sociaux
0 partages
0 tweets
2 plus
4 commentaires

Detecter les changements des fichiers dans un dossier

Comment surveiller un dossier du disque dur ? Eh oui, avec JAVA c'est possible depuis la version 7 du JRE, le package NIO intègre un service de détection de modification.
Java étant un langage multi-plateforme, le principe est de recevoir les événements (ChangeNotification sous Windows ou inotify sous Linux) du système d'exploitation. L'enregistrement à ces services est pris en charge par la JVM qui retransmets les messages à nos applications.

Note: la JVM et le JDK 1.7 doivent etre mis à jour pour utiliser la class WatchService.

Utiliser WatchService pour surveiller le dossier

La class FolderSpyWorker regroupe les fonctions d'enregistrement et de notification des événements. Les fonctions de WachService seront utilisées au travers d'une class Runnable permettant l'appel via un Thread.
Le dossier à surveiller est transmis dans le constructeur de la class. Pour l'exemple, les notifications sont simplement affichées dans la console, les événements peuvent prendre 4 valeurs distinctes:
- ENTRY_CREATE: un nouveau fichier est crée,
- ENTRY_MODIFY: un fichier est modifié dans le répertoire,
- ENTRY_DELETE: suppression d'un fichier,
- OVERFLOW: evenement perdu ou non traité.
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
 * Surveiller les changements dans un dossier
 * @author Axel
 * @see http://www.fobec.com/java/1126/detecter-changements-fichiers-dans-dossier.html
 */
public class FolderSpyWorker implements Runnable {
 
    private Path path = null;
 
    /**
     * Constructor
     * @param pathname String dossier à surveiller
     */
    public FolderSpyWorker(String pathname) {
        this.path = Paths.get(pathname);
        System.out.println("Start FolderSpy on:" + pathname);
    }
 
    /**
     * Worker
     */
    public void run() {
        WatchService watchService = null;
        try {
            watchService = this.path.getFileSystem().newWatchService();
            //Enregistrer les opérations à surveiller
            this.path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                    StandardWatchEventKinds.ENTRY_MODIFY,
                    StandardWatchEventKinds.ENTRY_DELETE);
 
            WatchKey watchKey;
            // boucle sans fin
            while (!Thread.interrupted()) {
                watchKey = watchService.take();
 
                //traiter les evenements
                for (WatchEvent<?> event : watchKey.pollEvents()) {
                    String fileName = event.context().toString();
                    if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
                        System.out.println("new file create "+fileName);
                    } else if (StandardWatchEventKinds.ENTRY_MODIFY.equals(event.kind())) {
                        System.out.println(fileName+" has been modified");
                    } else if (StandardWatchEventKinds.ENTRY_DELETE.equals(event.kind())) {
                        System.out.println(fileName+" has been deleted");
                    } else if (StandardWatchEventKinds.OVERFLOW.equals(event.kind())) {
                        System.out.println("Strange event");
                        continue;
                    }
                }
                //se place en attente de message
                watchKey.reset();
            }
        } catch (InterruptedException ex) {
            try {
                if (watchService!=null) watchService.close();
                System.out.println("Stop FolderSpy");
            } catch (IOException ex1) {
                Logger.getLogger(FolderSpyWorker.class.getName()).log(Level.SEVERE, null, ex1);
            }
        } catch (Exception ex) {
            Logger.getLogger(FolderSpyWorker.class.getName()).log(Level.SEVERE, null, ex);
        }
    }  
}

Notifier les modifications avec un Thread

Le thread permet d'isoler et contrôler plus facilement les opérations. Dans cet exemple, le dossier à surveiller est passé dans le constructeur de FolderSpyWorker à savoir c:temp. Le thread démarre et s'arrête tout seul au bout de 30 secondes. Les événements de modification, de création et de suppression sont notifiés dans la console.
/**
 * Exemple: Surveiller un répertoire avec un thread
 * @author Axel
 * @see http://www.fobec.com/java/1126/detecter-changements-fichiers-dans-dossier.html
 */
public class FolderSpySample {
 
    public static void main(String[] args) throws InterruptedException {
        //Créer le worker
        FolderSpyWorker folderSpyWorker=new FolderSpyWorker("c://temp//");
        //Créer le thred
        Thread folderSpyThread = new Thread(folderSpyWorker);
        //Lancer le thread
        folderSpyThread.start();         
        //Patienter 30 secondes
        Thread.sleep(30000);
        //Fermer le Thread
        folderSpyThread.interrupt();
    }
}

Ajouter un commentaire

Les champs marqués d'un * sont obligatoires, les adresses emails se sont pas publiées.
avatar bakouz

Publié par bakouz

le 12/10/2013 à 20:58:07

Bonjour Axel,
je suis tombe sur ton site un peu par hasard.
Hasard car je ne le connaissais pas jusqu'a maintenant, et non du hasard car c'est exactement ce genre de class que je recherchais. !
Donc je te remercie pour cela! et je mets ton site dans mes favoris, pour regarder le contenu que tu proposes :

Bonne fin de soire, cordialement

avatar Kezouille

Publié par Kezouille

le 19/12/2013 à 12:25:53

Bonjour Axel,

Merci pour ce petit guide qui m'a bien aide dans ma tache. En effet j'ai developpe une petite application afin de detecter l'ajout d'un fichier une image dans un repertoire et de lancer son impression automatique. Tout fonctionne correctement tant que le dossier que je surveille est sur ma machine. Mais des lors que je demande la surveillance d'un dossier place sur le reseau, l'application se lance, puis se termine quelques secondes apres, sans aucun message d'erreur ou information supplementaire. Cela ne vient pas des droits d'acces, je les ai, et je peux via cette application, ecrire dans le dossier reseau concerne. Merci de m'eclairer si vous avez une idee ou un debut de solution :D.
Bonne journee et bientot

avatar Axel

Publié par Axel

le 19/12/2013 à 12:46:31

Bonjour Kezouille,
je viens de tester sur notre LAN (serveur Windows 7), la surveillance a l'air de marcher.
De votre cote, s'agit-il d'un serveur sous Windows ou sous Linux ?
Pouvez-vous indiquer la valeur retour de la fonction this.path.getFileSystem().newWatchService() ?

avatar victor

Publié par victor

le 18/10/2014 à 10:42:47

Merci, je cherchais un code de ce genre !
A +

A lire aussi

Réseaux sociaux
Présentation de l'article
Catégorie
java - sources
Mise a jour
15/05/2013
Visualisation
vu 5190 fois
Public
Internaute
Auteur de la publication
Axel
Membre junior
Auteur de 51 articles
|BIO_PSEUDO|
Commentaires récents

Publié par Berenger dans java

Bonjour Mr Foebec je suis vraiment très content de cette réponse vous êtes simplement génial. quand je pense au nombre de jour que ça m'a pris et le temps que j'ai pe...

Publié par Etiazam dans php5

Si je peux me permettre, il manque l'incrementation dans les deux boucles, telles qu'elles sont presentees elles font tourner le navigateur en rond, il faut donc ajouter
for ($x=0;$x<50;$x...

Publié par Kal747 dans php5

Merci pour l'info !

Publié par Jacques dans CMS

Cette méthode produit une gamme de gris qui ne tient pas compte des caractéristiques de la vision humaine.
En vidéo on utilise la fonction luminance qui représente mieux les jaunes et les ve...

Publié par neuro dans CMS

exemple edifaint et trés interessant