Question

Je souhaite être averti lorsqu'un fichier a été modifié dans le système de fichiers. Je n'ai rien trouvé d'autre qu'un fil qui interroge la propriété lastModified File et cette solution n'est clairement pas optimale.

Était-ce utile?

La solution

Au niveau bas, le seul moyen de modéliser cet utilitaire consiste à interroger les répertoires sur un répertoire et à surveiller les attributs du fichier. Mais vous pouvez utiliser des modèles pour développer un adaptateur pour un tel utilitaire.

Par exemple, les serveurs d’applications j2ee tels que Tomcat et d’autres disposent d’une fonction de chargement automatique dans laquelle, dès que le descripteur de déploiement change ou que la classe de servlet change, le redémarrage de l’application.

Vous pouvez utiliser les bibliothèques de tels serveurs car la plupart du code de tomcat est réutilisable et opensource.

Autres conseils

J'ai déjà écrit un moniteur de fichier journal et j'ai constaté que l'impact sur les performances du système de l'interrogation des attributs d'un fichier unique, plusieurs fois par seconde, était en réalité très faible.

Java 7, dans le cadre de NIO.2, a ajouté l’ API WatchService.

  

L'API WatchService est conçue pour les applications nécessitant une notification des événements de modification de fichier.

J'utilise l'API VFS d'Apache Commons, voici un exemple de surveillance d'un fichier sans impact important sur les performances:

DefaultFileMonitor

Il existe une bibliothèque appelée jnotify qui englobe inotify sur linux et supporte également Windows. Je ne l'ai jamais utilisé et je ne sais pas à quel point c'est bon, mais ça vaut le coup d'essayer, je dirais.

Java commons-io a un FileAlterationObserver . il effectue une interrogation en combinaison avec un FileAlterationMonitor. Similaire à VFS commun. L'avantage est qu'il a beaucoup moins de dépendances.

edit: Moins de dépendances n’est pas vrai, elles sont facultatives pour VFS. Mais il utilise java File au lieu de la couche d’abstraction VFS.

& "Autres fonctionnalités NIO &"; dispose d'une fonctionnalité de surveillance de fichiers, avec une implémentation dépendante du système d'exploitation sous-jacent. Devrait être dans JDK7.

Je lance cet extrait de code chaque fois que je lis le fichier de propriétés, ne le lisant réellement que s'il a été modifié depuis la dernière fois que je l'ai lu. J'espère que cela aide quelqu'un.

private long timeStamp;
private File file;

private boolean isFileUpdated( File file ) {
  this.file = file;
  this.timeStamp = file.lastModified();

  if( this.timeStamp != timeStamp ) {
    this.timeStamp = timeStamp;
    //Yes, file is updated
    return true;
  }
  //No, file is not updated
  return false;
}

Une approche similaire est utilisée dans Log4J FileWatchdog .

Vous pouvez écouter les modifications de fichiers à l’aide d’un FileReader. Plz voir l'exemple ci-dessous

// File content change listener 
private String fname;
private Object lck = new Object();
... 
public void run()
{
    try
    {
        BufferedReader br = new BufferedReader( new FileReader( fname ) );
        String s;
        StringBuilder buf = new StringBuilder();
        while( true )
        {
            s = br.readLine();
            if( s == null )
            {
                synchronized( lck )
                {
                    lck.wait( 500 );
                }
            }
            else
            {
               System.out.println( "s = " + s );
            }

        }
    }
    catch( Exception e )
    {
        e.printStackTrace();
    }
}

Si vous êtes prêt à vous séparer avec de l'argent, JNIWrapper est une bibliothèque utile avec un Winpack, vous pourrez obtenir des événements du système de fichiers sur certains fichiers. Malheureusement, fenêtres uniquement.

Voir https://www.teamdev.com/jniwrapper .

Sinon, le recours au code natif n’est pas toujours une mauvaise chose, en particulier lorsque le meilleur des mécanismes proposés est un mécanisme de sondage par rapport à un événement natif.

J'ai remarqué que les opérations du système de fichiers Java peuvent être lentes sur certains ordinateurs et peuvent facilement affecter les performances de l'application si elles ne sont pas gérées correctement.

Vous pouvez également considérer Apache Commons JCI (interface de compilation Java). Bien que cette API semble être axée sur la compilation dynamique de classes, elle inclut également des classes dans son API qui surveillent les modifications de fichiers.

Exemple: http://commons.apache.org/jci/usage.html

Spring Integration offre un mécanisme intéressant pour consulter les répertoires et les fichiers: http: / /static.springsource.org/spring-integration/reference/htmlsingle/#files . Je suis presque sûr que c'est multi-plateforme (je l'ai utilisé sur mac, linux et windows).

JxFileWatcher est une bibliothèque commerciale interservices pour les fichiers et les dossiers surveillés. Il peut être téléchargé à partir d'ici: http://www.teamdev.com/jxfilewatcher/

Vous pouvez également le voir en action en ligne:   http://www.teamdev.com/jxfilewatcher/onlinedemo/

Interroger la dernière propriété de fichier modifiée est une solution simple mais efficace. Il suffit de définir une classe qui étend mon FileChangedWatcher et d'implémenter la onModified() méthode:

import java.io.File;

public abstract class FileChangedWatcher
{
    private File file;

    public FileChangedWatcher(String filePath)
    {
        file = new File(filePath);
    }

    public void watch() throws InterruptedException
    {
        long currentModifiedDate = file.lastModified();

        while (true)
        {
            long newModifiedDate = file.lastModified();

            if (newModifiedDate != currentModifiedDate)
            {
                currentModifiedDate = newModifiedDate;
                onModified();
            }

            Thread.sleep(100);
        }
    }

    public String getFilePath()
    {
        return file.getAbsolutePath();
    }

    protected abstract void onModified();
}

Semblable aux autres réponses, voici comment je l'ai fait en utilisant File, Timer et TimerTask pour laisser cette tâche s'exécuter en tant que scrutation de thread en arrière-plan à des intervalles définis.

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

public class FileModifiedWatcher
{
  private static File file;
  private static int pollingInterval;
  private static Timer fileWatcher;
  private static long lastReadTimeStamp = 0L;

  public static boolean init(String _file, int _pollingInterval)
  {
    file =  new File(_file);
    pollingInterval = _pollingInterval; // In seconds

    watchFile();

    return true;
  }

  private static void watchFile()
  {
    if ( null == fileWatcher )
    {
      System.out.println("START");

      fileWatcher = new Timer();

      fileWatcher.scheduleAtFixedRate(new TimerTask()
      {
        @Override
        public void run()
        {

          if ( file.lastModified() > lastReadTimeStamp )
          {
            System.out.println("File Modified");
          }

          lastReadTimeStamp = System.currentTimeMillis();
        }
      }, 0, 1000 * pollingInterval);
    }

  }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top